Ejemplo n.º 1
0
        private WaitHandle[] SelectWaitMode(WaitHandle[] paranoidModeHandles, WaitHandle[] memoryAvailableHandles)
        {
            var memoryInfoResult = MemoryInformation.GetMemoryInfo();
            var handles          = (memoryInfoResult.AvailableMemory + GetCurrentProcessMemoryMappedShared()).GetValue(SizeUnit.Bytes) <
                                   _lowMemoryThreshold * 2 ? paranoidModeHandles : memoryAvailableHandles;

            return(handles);
        }
Ejemplo n.º 2
0
        public static Size GetCurrentProcessMemoryMappedShared()
        {
            // because we are usually using memory mapped files, we don't want
            // to account for memory that was loaded into our own working set
            // but that the OS can discard with no cost (because it can load
            // the data from disk without needing to write it)

            var stats = MemoryInformation.MemoryStats();

            var sharedMemory = stats.WorkingSet - stats.TotalUnmanagedAllocations - stats.ManagedMemory - stats.MappedTemp;

            // if this is negative, we'll just ignore this
            var mappedShared = new Size(Math.Max(0, sharedMemory), SizeUnit.Bytes);

            return(mappedShared);
        }
Ejemplo n.º 3
0
        private void SimulateLowMemory()
        {
            _simulatedLowMemory.Reset();
            LowMemoryState = !LowMemoryState;
            var memInfoForLog      = MemoryInformation.GetMemoryInfo();
            var availableMemForLog = memInfoForLog.AvailableMemory.GetValue(SizeUnit.Bytes);

            AddLowMemEvent(LowMemoryState ? LowMemReason.LowMemStateSimulation : LowMemReason.BackToNormalSimulation,
                           availableMemForLog,
                           -2,
                           memInfoForLog.TotalPhysicalMemory.GetValue(SizeUnit.Bytes),
                           memInfoForLog.CurrentCommitCharge.GetValue(SizeUnit.Bytes));
            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Simulating : " + (LowMemoryState ? "Low memory event" : "Back to normal memory usage"));
            }
            RunLowMemoryHandlers(LowMemoryState);
        }
Ejemplo n.º 4
0
        private void MonitorMemoryUsage()
        {
            NativeMemory.EnsureRegistered();
            int clearInactiveHandlersCounter = 0;
            var memoryAvailableHandles       = new WaitHandle[] { _simulatedLowMemory, _shutdownRequested };
            var paranoidModeHandles          = new WaitHandle[] { _simulatedLowMemory, _shutdownRequested, _warnAllocation };
            var timeout = 5 * 1000;

            while (true)
            {
                long totalUnmanagedAllocations = 0;

                var handles = SelectWaitMode(paranoidModeHandles, memoryAvailableHandles);
                switch (WaitHandle.WaitAny(handles, timeout))
                {
                case WaitHandle.WaitTimeout:
                    if (++clearInactiveHandlersCounter > 60)     // 5 minutes == WaitAny 5 Secs * 60
                    {
                        clearInactiveHandlersCounter = 0;
                        ClearInactiveHandlers();
                    }
                    foreach (var stats in NativeMemory.ThreadAllocations.Values)
                    {
                        if (stats.ThreadInstance.IsAlive == false)
                        {
                            continue;
                        }

                        totalUnmanagedAllocations += stats.TotalAllocated;
                    }

                    var memInfo = MemoryInformation.GetMemoryInfo();

                    var currentProcessMemoryMappedShared = GetCurrentProcessMemoryMappedShared();
                    var availableMem = (memInfo.AvailableMemory + currentProcessMemoryMappedShared).GetValue(SizeUnit.Bytes);

                    if (availableMem < _lowMemoryThreshold &&
                        // at all times, we want 2% or 1 GB, the lowest of the two
                        memInfo.AvailableMemory < Size.Min((memInfo.TotalPhysicalMemory / 50), new Size(1, SizeUnit.Gigabytes)))
                    {
                        if (LowMemoryState == false)
                        {
                            if (_logger.IsInfoEnabled)
                            {
                                _logger.Info("Low memory detected, will try to reduce memory usage...");
                            }
                            AddLowMemEvent(LowMemReason.LowMemOnTimeoutChk, availableMem, totalUnmanagedAllocations,
                                           memInfo.TotalPhysicalMemory.GetValue(SizeUnit.Bytes));
                        }
                        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, availableMem, totalUnmanagedAllocations, memInfo.TotalPhysicalMemory.GetValue(SizeUnit.Bytes));
                        }
                        LowMemoryState = false;
                        RunLowMemoryHandlers(false);
                        timeout = availableMem < _lowMemoryThreshold * 2 ? 1000 : 5000;
                    }
                    break;

                case 0:
                    _simulatedLowMemory.Reset();
                    LowMemoryState = !LowMemoryState;
                    var memInfoForLog      = MemoryInformation.GetMemoryInfo();
                    var availableMemForLog = memInfoForLog.AvailableMemory.GetValue(SizeUnit.Bytes);
                    AddLowMemEvent(LowMemoryState ? LowMemReason.LowMemStateSimulation : LowMemReason.BackToNormalSimulation, availableMemForLog,
                                   totalUnmanagedAllocations, memInfoForLog.TotalPhysicalMemory.GetValue(SizeUnit.Bytes));
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info("Simulating : " + (LowMemoryState ? "Low memory event" : "Back to normal memory usage"));
                    }
                    RunLowMemoryHandlers(LowMemoryState);
                    break;

                case 2:     // check allocations
                    _warnAllocation.Reset();
                    goto case WaitHandle.WaitTimeout;

                case 1:     // shutdown requested
                    return;

                default:
                    return;
                }
            }
        }
Ejemplo n.º 5
0
        private void MonitorMemoryUsage()
        {
            NativeMemory.EnsureRegistered();
            int  clearInactiveHandlersCounter = 0;
            var  memoryAvailableHandles       = new WaitHandle[] { _simulatedLowMemory, _shutdownRequested };
            var  paranoidModeHandles          = new WaitHandle[] { _simulatedLowMemory, _shutdownRequested, _warnAllocation };
            var  timeout = 5 * 1000;
            long totalUnmanagedAllocations = 0;

            while (true)
            {
                var handles = MemoryInformation.GetMemoryInfo().AvailableMemory.GetValue(SizeUnit.Bytes) < _lowMemoryThreshold * 2 ?
                              paranoidModeHandles :
                              memoryAvailableHandles;
                switch (WaitHandle.WaitAny(handles, timeout))
                {
                case WaitHandle.WaitTimeout:
                    if (++clearInactiveHandlersCounter > 60)     // 5 minutes == WaitAny 5 Secs * 60
                    {
                        clearInactiveHandlersCounter = 0;
                        ClearInactiveHandlers();
                    }
                    foreach (var stats in NativeMemory.ThreadAllocations.Values)
                    {
                        if (stats.ThreadInstance.IsAlive == false)
                        {
                            continue;
                        }

                        totalUnmanagedAllocations += stats.TotalAllocated;
                    }

                    var memInfo = MemoryInformation.GetMemoryInfo();

                    var availableMem = memInfo.AvailableMemory.GetValue(SizeUnit.Bytes);
                    if (availableMem < _lowMemoryThreshold &&
                        totalUnmanagedAllocations > memInfo.TotalPhysicalMemory.GetValue(SizeUnit.Bytes) * _physicalRatioForLowMemDetection)
                    {
                        if (LowMemoryState == false && _logger.IsInfoEnabled)
                        {
                            _logger.Info("Low memory detected, will try to reduce memory usage...");
                        }
                        LowMemoryState = true;
                        clearInactiveHandlersCounter = 0;
                        RunLowMemoryHandlers(true);
                        timeout = 500;
                    }
                    else
                    {
                        if (LowMemoryState && _logger.IsInfoEnabled)
                        {
                            _logger.Info("Back to normal memory usage detected");
                        }
                        LowMemoryState = false;
                        RunLowMemoryHandlers(false);
                        timeout = availableMem < _lowMemoryThreshold * 2 ? 1000 : 5000;
                    }
                    break;

                case 0:
                    _simulatedLowMemory.Reset();
                    LowMemoryState = !LowMemoryState;
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info("Simulating : " + (LowMemoryState ? "Low memory event" : "Back to normal memory usage"));
                    }
                    RunLowMemoryHandlers(LowMemoryState);
                    break;

                case 2:     // check allocations
                    _warnAllocation.Reset();
                    goto case WaitHandle.WaitTimeout;

                case 1:     // shutdown requested
                    return;

                default:
                    return;
                }
            }
        }
Ejemplo n.º 6
0
        internal int CheckMemoryStatus(SmapsReader smapsReader)
        {
            int  timeout;
            bool isLowMemory;
            long totalUnmanagedAllocations;

            (Size AvailableMemory, Size TotalPhysicalMemory, Size CurrentCommitCharge)stats;
            try
            {
                totalUnmanagedAllocations = MemoryInformation.GetUnManagedAllocationsInBytes();
                isLowMemory = GetLowMemory(out stats, smapsReader);
            }
            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);
        }