public static bool IsEarlyOutOfMemory(MemoryInfoResult memInfo, out Size commitChargeThreshold) { if (PlatformDetails.RunningOnPosix && // we only _need_ this check on Windows EnableEarlyOutOfMemoryCheck == false) // but we want to enable this manually if needed { commitChargeThreshold = Size.Zero; return(false); } return(IsEarlyOutOfMemoryInternal(memInfo, earlyOutOfMemoryWarning: true, out commitChargeThreshold)); }
private static bool IsEarlyOutOfMemoryInternal(MemoryInfoResult memInfo, bool earlyOutOfMemoryWarning, out Size commitChargeThreshold) { // if we are about to create a new thread, might not always be a good idea: // https://ayende.com/blog/181537-B/production-test-run-overburdened-and-under-provisioned // https://ayende.com/blog/181569-A/threadpool-vs-pool-thread Size overage; if (memInfo.CurrentCommitCharge > memInfo.TotalCommittableMemory) { // this can happen on containers, since we get this information from the host, and // sometimes this kind of stat is shared, see: // https://fabiokung.com/2014/03/13/memory-inside-linux-containers/ commitChargeThreshold = GetMinCommittedToKeep(memInfo.TotalPhysicalMemory); overage = commitChargeThreshold + //extra to keep free (memInfo.TotalPhysicalMemory - memInfo.AvailableMemory); //actually in use now return(overage >= memInfo.TotalPhysicalMemory); } commitChargeThreshold = GetMinCommittedToKeep(memInfo.TotalCommittableMemory); overage = commitChargeThreshold + memInfo.CurrentCommitCharge; return(overage >= memInfo.TotalCommittableMemory); Size GetMinCommittedToKeep(Size currentValue) { var minFreeToKeep = Size.Min(_maxFreeCommittedMemoryToKeep, currentValue * _minimumFreeCommittedMemoryPercentage); if (earlyOutOfMemoryWarning) { return(Size.Min( _lowMemoryCommitLimitInMb, // needs to be bigger than the MaxFreeCommittedMemoryToKeep Size.Max(currentValue / 20, minFreeToKeep * 1.5))); } return(minFreeToKeep); } }
private static void ThrowInsufficientMemory(MemoryInfoResult memInfo) { LowMemoryNotification.Instance.SimulateLowMemoryNotification(); throw new EarlyOutOfMemoryException($"The amount of available memory to commit on the system is low. Commit charge: {memInfo.CurrentCommitCharge} / {memInfo.TotalCommittableMemory}. Memory: {memInfo.TotalPhysicalMemory - memInfo.AvailableMemory} / {memInfo.TotalPhysicalMemory}"); }
public abstract bool IsEarlyOutOfMemory(MemoryInfoResult memInfo, out Size commitChargeThreshold);
public EarlyOutOfMemoryException(string message, MemoryInfoResult memoryInfo) : base(message) { MemoryInfo = memoryInfo; }
private static void ThrowInsufficentMemory(MemoryInfoResult memInfo) { throw new InsufficientExecutionStackException($"The amount of available memory to commit on the system is low. Commit charge: {memInfo.CurrentCommitCharge} / {memInfo.TotalCommittableMemory}. Memory: {memInfo.TotalPhysicalMemory - memInfo.AvailableMemory} / {memInfo.TotalPhysicalMemory}" + $" Will not create a new thread in this situation because it may result in a stack overflow error when trying to allocate stack space but there isn't sufficient memory for that."); }