private static bool CollectGarbageInternal(bool compactLoh, Action afterCollect, bool forceByUser, int maxGeneration, GCCollectionMode gcCollectionMode, bool waitForPendingFinalizers) { if (!ShouldCollectNow() && !forceByUser) { return(false); } ReleaseMemoryBeforeGC(); memoryBeforeLastForcedGC = GC.GetTotalMemory(false); if (compactLoh) { SetCompactLog.Value(); } GC.Collect(maxGeneration, gcCollectionMode); if (afterCollect != null) { afterCollect(); } if (waitForPendingFinalizers) { GC.WaitForPendingFinalizers(); } memoryAfterLastForcedGC = GC.GetTotalMemory(false); memoryDifferenceLastGc = DifferenceAsDecimalPercents(MemoryBeforeLastForcedGC, MemoryAfterLastForcedGC); log.Info("Finished GC, before was {0:#,#}kb, after is {1:#,#}kb", MemoryBeforeLastForcedGC, MemoryAfterLastForcedGC); // -> reset last time, increase delay threshold and disallow GC (too early!) lastForcedGCTime = SystemTime.UtcNow; var old = delayBetweenGCInMinutes; if (memoryDifferenceLastGc < 0.1) { delayBetweenGCInMinutes = Math.Max(5 + delayBetweenGCInMinutes, MaxDelayBetweenGCInMinutes); if (old != delayBetweenGCInMinutes) { log.Debug("Increasing delay for forced GC (not enough memory released, so we need to back off). " + "New interval between GCs will be {0} minutes", delayBetweenGCInMinutes); } } else { if (old != delayBetweenGCInMinutes) { log.Debug("Resetting delay for forced GC (enough memory was released to make it useful, so we don't need to back off). " + "New interval between GCs will be {0} minutes", delayBetweenGCInMinutes); } delayBetweenGCInMinutes = DefaultDelayBetweenGCInMinutes; } return(true); }
public static void CollectGarbage(bool compactLoh, Action afterCollect) { GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); if (compactLoh) { SetCompactLog.Value(); } if (afterCollect != null) { afterCollect(); } GC.WaitForPendingFinalizers(); }