Пример #1
0
        public static long GetSharedCleanInBytes(Process process)
        {
            if (process == null)
            {
                return(0);
            }

            var mappedDirty = 0L;

            foreach (var mapping in NativeMemory.FileMapping)
            {
                var fileMappingInfo = mapping.Value.Value;
                var fileType        = fileMappingInfo.FileType;
                if (fileType == NativeMemory.FileType.Data)
                {
                    continue;
                }

                var totalMapped = GetTotalMapped(fileMappingInfo);
                if (fileType == NativeMemory.FileType.ScratchBuffer)
                {
                    // for scratch buffers we have the allocated size
                    var allocated = fileMappingInfo.GetAllocatedSizeFunc?.Invoke() ?? totalMapped;
                    if (allocated < totalMapped / 2)
                    {
                        // using less than half of the size of the scratch buffer
                        mappedDirty += allocated;
                        continue;
                    }
                }

                // we are counting the total mapped size of all the other buffers
                mappedDirty += totalMapped;
            }

            var sharedClean = process.WorkingSet64 - AbstractLowMemoryMonitor.GetUnmanagedAllocationsInBytes() - AbstractLowMemoryMonitor.GetManagedMemoryInBytes() - mappedDirty;

            // the shared dirty can be larger than the size of the working set
            // this can happen when some of the buffers were paged out
            return(Math.Max(0, sharedClean));
        }
Пример #2
0
        internal int CheckMemoryStatus(AbstractLowMemoryMonitor monitor)
        {
            int  timeout;
            bool isLowMemory;
            long totalUnmanagedAllocations;

            (Size AvailableMemory, Size TotalPhysicalMemory, Size CurrentCommitCharge)stats;
            try
            {
                totalUnmanagedAllocations = AbstractLowMemoryMonitor.GetUnmanagedAllocationsInBytes();
                isLowMemory = GetLowMemory(out stats, monitor);
            }
            catch (OutOfMemoryException)
            {
                isLowMemory = true;
                stats       = (new Size(), new Size(), new Size());
                totalUnmanagedAllocations = -1;
            }
            if (isLowMemory)
            {
                if (LowMemoryState == false)
                {
                    try
                    {
                        if (_logger.IsInfoEnabled)
                        {
                            _logger.Info("Low memory detected, will try to reduce memory usage...");
                        }
                        AddLowMemEvent(LowMemReason.LowMemOnTimeoutChk,
                                       stats.AvailableMemory.GetValue(SizeUnit.Bytes),
                                       totalUnmanagedAllocations,
                                       stats.TotalPhysicalMemory.GetValue(SizeUnit.Bytes),
                                       stats.CurrentCommitCharge.GetValue(SizeUnit.Bytes));
                    }
                    catch (OutOfMemoryException)
                    {
                        // nothing we can do, we'll wait and try again
                    }
                }
                LowMemoryState = true;
                _clearInactiveHandlersCounter = 0;
                RunLowMemoryHandlers(true);
                timeout = 500;
            }
            else
            {
                if (LowMemoryState)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info("Back to normal memory usage detected");
                    }
                    AddLowMemEvent(LowMemReason.BackToNormal,
                                   stats.AvailableMemory.GetValue(SizeUnit.Bytes),
                                   totalUnmanagedAllocations,
                                   stats.TotalPhysicalMemory.GetValue(SizeUnit.Bytes),
                                   stats.CurrentCommitCharge.GetValue(SizeUnit.Bytes));
                }
                LowMemoryState = false;
                RunLowMemoryHandlers(false);
                timeout = stats.AvailableMemory < LowMemoryThreshold * 2 ? 1000 : 5000;
            }

            return(timeout);
        }
Пример #3
0
        internal int CheckMemoryStatus(AbstractLowMemoryMonitor monitor)
        {
            int timeout;
            LowMemorySeverity isLowMemory;
            long totalUnmanagedAllocations;

            (Size AvailableMemory, Size TotalScratchDirtyMemory, Size TotalPhysicalMemory, Size CurrentCommitCharge)stats;
            try
            {
                if (_enableHighTemporaryDirtyMemoryUse)
                {
                    DirtyMemoryState = monitor.GetDirtyMemoryState();
                }

                totalUnmanagedAllocations = AbstractLowMemoryMonitor.GetUnmanagedAllocationsInBytes();
                isLowMemory = GetLowMemory(out stats, monitor);
            }
            catch (OutOfMemoryException)
            {
                isLowMemory = LowMemorySeverity.ExtremelyLow;
                stats       = (new Size(), new Size(), new Size(), new Size());
                totalUnmanagedAllocations = -1;
            }
            if (isLowMemory != LowMemorySeverity.None)
            {
                if (LowMemoryState == false)
                {
                    try
                    {
                        if (_logger.IsInfoEnabled)
                        {
                            _logger.Info("Low memory detected, will try to reduce memory usage...");
                        }
                        AddLowMemEvent(LowMemReason.LowMemOnTimeoutChk,
                                       stats.AvailableMemory.GetValue(SizeUnit.Bytes),
                                       totalUnmanagedAllocations,
                                       stats.TotalScratchDirtyMemory.GetValue(SizeUnit.Bytes),
                                       stats.TotalPhysicalMemory.GetValue(SizeUnit.Bytes),
                                       stats.CurrentCommitCharge.GetValue(SizeUnit.Bytes));
                    }
                    catch (OutOfMemoryException)
                    {
                        // nothing we can do, we'll wait and try again
                    }
                }
                LowMemoryState = true;

                timeout = 500;

                if (isLowMemory == LowMemorySeverity.Low &&
                    (PlatformDetails.RunningOnLinux == false || PlatformDetails.RunningOnMacOsx))
                {
                    isLowMemory = LowMemorySeverity.ExtremelyLow; // On linux we want two severity steps
                }
                _clearInactiveHandlersCounter = 0;
                RunLowMemoryHandlers(true, isLowMemory);
            }
            else
            {
                if (LowMemoryState)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info("Back to normal memory usage detected");
                    }
                    AddLowMemEvent(LowMemReason.BackToNormal,
                                   stats.AvailableMemory.GetValue(SizeUnit.Bytes),
                                   totalUnmanagedAllocations,
                                   stats.TotalScratchDirtyMemory.GetValue(SizeUnit.Bytes),
                                   stats.TotalPhysicalMemory.GetValue(SizeUnit.Bytes),
                                   stats.CurrentCommitCharge.GetValue(SizeUnit.Bytes));
                }
                LowMemoryState = false;
                RunLowMemoryHandlers(false);
                timeout = stats.AvailableMemory < LowMemoryThreshold * 2 ? 1000 : 5000;
            }

            return(timeout);
        }