The 对象池 http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis/ObjectPool%25601.cs,20b9a041fb2d5b00是 Roslyn C# 编译器中使用的一种类型,用于重用经常使用的对象,这些对象通常会经常更新和垃圾收集。这减少了必须发生的垃圾收集操作的数量和大小。
Roslyn 编译器似乎有几个独立的对象池,每个池都有不同的大小。我想知道为什么有这么多实现、首选实现是什么以及为什么他们选择 20、100 或 128 的池大小。
1 - 共享池 http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.Workspaces/Utilities/ObjectPools/SharedPools.cs,b2114905209e7df3- 存储 20 个对象的池,如果使用 BigDefault,则存储 100 个对象。这个也很奇怪,因为它创建了一个新的 PooledObject 实例,当我们尝试池化对象而不是创建和销毁新对象时,这是没有意义的。
// Example 1 - In a using statement, so the object gets freed at the end.
using (PooledObject<Foo> pooledObject = SharedPools.Default<List<Foo>>().GetPooledObject())
{
// Do something with pooledObject.Object
}
// Example 2 - No using statement so you need to be sure no exceptions are not thrown.
List<Foo> list = SharedPools.Default<List<Foo>>().AllocateAndClear();
// Do something with list
SharedPools.Default<List<Foo>>().Free(list);
// Example 3 - I have also seen this variation of the above pattern, which ends up the same as Example 1, except Example 1 seems to create a new instance of the IDisposable [PooledObject<T>][3] object. This is probably the preferred option if you want fewer GC's.
List<Foo> list = SharedPools.Default<List<Foo>>().AllocateAndClear();
try
{
// Do something with list
}
finally
{
SharedPools.Default<List<Foo>>().Free(list);
}
2 - ListPool http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.Workspaces/Formatting/ListPool.cs,1086fa28bcfcb8ca and 字符串生成器池 http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.Workspaces/Formatting/StringBuilderPool.cs,039ef0c630df07c3- 不是严格独立的实现,而是上面所示的 SharedPools 实现的包装器,专门用于 List 和 StringBuilder。因此,这会重新使用 SharedPools 中存储的对象池。
// Example 1 - No using statement so you need to be sure no exceptions are thrown.
StringBuilder stringBuilder= StringBuilderPool.Allocate();
// Do something with stringBuilder
StringBuilderPool.Free(stringBuilder);
// Example 2 - Safer version of Example 1.
StringBuilder stringBuilder= StringBuilderPool.Allocate();
try
{
// Do something with stringBuilder
}
finally
{
StringBuilderPool.Free(stringBuilder);
}
3 - 混合词典 http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis/PooledDictionary.cs,ebb1ac303c777646 and 池化哈希集 http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis/PooledHashSet.cs,afe982be5207ab5e- 它们直接使用 ObjectPool 并具有完全独立的对象池。存储 128 个对象的池。
// Example 1
PooledHashSet<Foo> hashSet = PooledHashSet<Foo>.GetInstance()
// Do something with hashSet.
hashSet.Free();
// Example 2 - Safer version of Example 1.
PooledHashSet<Foo> hashSet = PooledHashSet<Foo>.GetInstance()
try
{
// Do something with hashSet.
}
finally
{
hashSet.Free();
}
Update
.NET Core 中有新的对象池实现。请参阅我的回答C# 对象池模式实现 https://stackoverflow.com/questions/2510975/c-sharp-object-pooling-pattern-implementation/30664859#30664859问题。