예제 #1
0
        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));
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
 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}");
 }
예제 #4
0
 public abstract bool IsEarlyOutOfMemory(MemoryInfoResult memInfo, out Size commitChargeThreshold);
예제 #5
0
 public EarlyOutOfMemoryException(string message, MemoryInfoResult memoryInfo) : base(message)
 {
     MemoryInfo = memoryInfo;
 }
예제 #6
0
 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.");
 }