GC.Collect()和GC.Collect(GC.MaxGeneration)有什么区别?

时间:2013-04-08 10:21:28

标签: c# .net garbage-collection

我见过多个安慰者,建议你运行GC.Collect(GC.MaxGeneration) 由于方法GC.Collect()将收集所有现有的世代,两者之间有什么区别吗?

也许如果只有两代而不是三代,那么GC会收集两代,并且不会尝试收集第三代,这将提高性能。但说真的,这有意义吗?

5 个答案:

答案 0 :(得分:2)

唯一的区别是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
}

答案 1 :(得分:1)

GC.Collect()可能无所作为,因为它使用&#39;优化&#39;对于GCCollectionMode

MSDN on Optimized-&gt;允许垃圾收集器确定当前时间是否是回收对象的最佳时间。

GC.Collect(GC.MaxGeneration)使用强制&#39;对于GCCollectionMode

MSDN on Forced - &gt;强制垃圾收集立即发生。

两者都会尝试回收所有世代。

答案 2 :(得分:0)

GC.Collect()使用GCCollectionMode.DefaultGC.Collect(GC.MaxGeneration)

也是如此

那么,之间没有区别!


根据MSDN

GCCollectionMode枚举

  

默认值:此枚举的默认设置,即   目前被迫。
强迫:强制进行垃圾收集   立即发生。
优化:允许垃圾   收集器,以确定当前时间是否是最佳回收   对象。

使用反射器:

[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);
}

P.S。0GCCollectionMode.Default相同。

答案 3 :(得分:0)

标准(系统启动的)垃圾收集的行为是:

  1. 从GenX中删除所有未植根的项目(即从活动代码中引用)
  2. 将所有剩余项目从GenX升级到GenX + 1
  3. 如果新项目的GenX + 1空间不足,请重复上述GenX + 1
  4. 因此,标准集合可能只收集Gen0,并将一些数据随机播放到Gen1中,然后停止。这有助于延长到达Gen2的物体的寿命:Gen2的收集频率比Gen0低得多,因此到达Gen2的物体可能会暂停一段时间。

    如果强制收集所有代,将立即收集Gen2中的对象。这将释放更多内存,但也会对性能产生影响。

    最重要的是,任何收藏都会将根源项目推广到下一代。这是手动收藏不好的一个原因:物品将被不必要地提升到Gen1 / 2,然后实际上会更长时间停留(除非您反复使用手动GC,这只会使问题复杂化......)。

答案 4 :(得分:-1)

这是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);
}

在这里你可以看到你们两个方法调用带有两个参数的收集方法。收集(int genration,GCCollectionMode模式)。