我看到多篇答案建议运行GC.Collect(GC.MaxGeneration)
。
由于方法GC.Collect()
将收集所有现有的代,这两者之间有什么区别吗?
也许如果存在的是两个代而不是三个代,GC将收集两个代,并且不会尝试收集第三代,这将提高性能。 但是,这真的有意义吗?
我看到多篇答案建议运行GC.Collect(GC.MaxGeneration)
。
由于方法GC.Collect()
将收集所有现有的代,这两者之间有什么区别吗?
也许如果存在的是两个代而不是三个代,GC将收集两个代,并且不会尝试收集第三代,这将提高性能。 但是,这真的有意义吗?
GC.Collect()
将使用GCCollectionMode.Optimized
,而GC.Collect(GC.MaxGeneration)
将使用GCCollectionMode.Default
(至少在.NET Framework 4.5中)。还有一些重载可以手动指定收集模式。/// <summary>Specifies the behavior for a forced garbage collection.</summary>
public enum GCCollectionMode
{
/// <summary>The default setting for this enumeration, which is currently <see cref="F:System.GCCollectionMode.Forced" />. </summary>
Default,
/// <summary>Forces the garbage collection to occur immediately.</summary>
Forced,
/// <summary>Allows the garbage collector to determine whether the current time is optimal to reclaim objects. </summary>
Optimized
}
GC.Collect()可能不会起作用,因为它使用“优化”进行GCCollectionMode。
MSDN中的Optimized->允许垃圾回收器确定当前时间是否最适合回收对象。
GC.Collect(GC.MaxGeneration)使用“强制”进行GCCollectionMode
MSDN中的Forced->立即强制进行垃圾回收。
两种方法都会尝试恢复所有代。
标准(系统启动的)垃圾回收的行为如下:
因此,标准收集可能仅收集Gen0,并将一些数据移动到Gen1,然后停止。这有助于达到Gen2的对象的长寿命:Gen2比Gen0更不经常被收集,因此达到Gen2的对象可能会挂起一段时间。
如果强制对所有代进行收集,则Gen2中的对象将立即被收集。这将释放更多内存,但也会影响性能。
最重要的是,任何收集都会将根源项目提升到下一代。这是手动收集不好的原因之一:项目将不必要地被提升到Gen1/2,然后实际上会挂起更长时间(除非您反复使用手动GC,这只会加剧问题...)。
GC.Collect()
使用 GCCollectionMode.Default
,而 GC.Collect(GC.MaxGeneration)
也是这样。
[MethodImpl(MethodImplOptions.InternalCall)]
private static void nativeCollectGeneration(int generation, int mode);
public static void Collect()
{
GC.nativeCollectGeneration(-1, 0);
}
public static void Collect(int generation)
{
GC.Collect(generation, GCCollectionMode.Default);
}
附言:: 0
和 GCCollectionMode.Default
是相同的。
这是GC类的内部代码
// Forces a collection of all generations from 0 through Generation.
//
public static void Collect(int generation) {
Collect(generation, GCCollectionMode.Default);
}
// Garbage Collect all generations.
//
[System.Security.SecuritySafeCritical] // auto-generated
public static void Collect() {
//-1 says to GC all generations.
_Collect(-1, (int)GCCollectionMode.Default);
}
[System.Security.SecuritySafeCritical] // auto-generated
public static void Collect(int generation, GCCollectionMode mode)
{
if (generation<0)
{
throw new ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
if ((mode < GCCollectionMode.Default) || (mode > GCCollectionMode.Optimized))
{
throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_Enum"));
}
Contract.EndContractBlock();
_Collect(generation, (int)mode);
}
在这里,您可以看到两个方法调用都使用了两个参数调用Collect方法。Collect(int genration,GCCollectionMode mode)。