File: System\Runtime\Caching\MemoryMonitor.cs
Web Access
Project: src\src\libraries\System.Runtime.Caching\src\System.Runtime.Caching.csproj (System.Runtime.Caching)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics;
using System.Globalization;
 
namespace System.Runtime.Caching
{
    // MemoryMonitor is the base class for memory monitors.  The MemoryCache has two
    // types of monitors:  PhysicalMemoryMonitor and CacheMemoryMonitor.  The first monitors
    // the amount of physical memory used on the machine, and helps determine when we should
    // drop cache entries to avoid paging.  The second monitors the amount of memory used by
    // the cache itself, and helps determine when we should drop cache entries to avoid
    // exceeding the cache's memory limit.  Both are configurable (see ConfigUtil.cs).
    internal abstract partial class MemoryMonitor
    {
        protected const int TERABYTE_SHIFT = 40;
        protected const long TERABYTE = 1L << TERABYTE_SHIFT;
 
        protected const int GIGABYTE_SHIFT = 30;
        protected const long GIGABYTE = 1L << GIGABYTE_SHIFT;
 
        protected const int MEGABYTE_SHIFT = 20;
        protected const long MEGABYTE = 1L << MEGABYTE_SHIFT; // 1048576
 
        protected const int KILOBYTE_SHIFT = 10;
        protected const long KILOBYTE = 1L << KILOBYTE_SHIFT; // 1024
 
        protected const int HISTORY_COUNT = 6;
 
        protected int _pressureHigh;      // high pressure level
        protected int _pressureLow;       // low pressure level - slow growth here
 
        protected int _i0;
        protected int[] _pressureHist;
        protected int _pressureTotal;
 
#pragma warning disable CA1802, CS0649 // some builds initialize these to other values in a static cctor
        private static readonly long s_totalPhysical;
        private static readonly long s_totalVirtual;
#pragma warning restore CA1802, CS0649
 
        internal static long TotalPhysical => s_totalPhysical;
        internal static long TotalVirtual => s_totalVirtual;
 
        internal int PressureLast { get { return _pressureHist[_i0]; } }
        internal int PressureHigh { get { return _pressureHigh; } }
        internal int PressureLow { get { return _pressureLow; } }
 
        internal bool IsAboveHighPressure()
        {
            return PressureLast >= PressureHigh;
        }
 
        protected abstract int GetCurrentPressure();
 
        internal abstract int GetPercentToTrim(DateTime lastTrimTime, int lastTrimPercent);
 
        protected void InitHistory()
        {
            Debug.Assert(_pressureHigh > 0, "_pressureHigh > 0");
            Debug.Assert(_pressureLow > 0, "_pressureLow > 0");
            Debug.Assert(_pressureLow <= _pressureHigh, "_pressureLow <= _pressureHigh");
 
            int pressure = GetCurrentPressure();
 
            _pressureHist = new int[HISTORY_COUNT];
            for (int i = 0; i < HISTORY_COUNT; i++)
            {
                _pressureHist[i] = pressure;
                _pressureTotal += pressure;
            }
        }
 
        // Get current pressure and update history
        internal void Update()
        {
            int pressure = GetCurrentPressure();
 
            _i0 = (_i0 + 1) % HISTORY_COUNT;
            _pressureTotal -= _pressureHist[_i0];
            _pressureTotal += pressure;
            _pressureHist[_i0] = pressure;
 
            Dbg.Trace("MemoryCacheStats", this.GetType().Name + ".Update: last=" + pressure
                        + ",high=" + PressureHigh
                        + ",low=" + PressureLow
                        + " " + DateTime.Now.ToString("o", CultureInfo.InvariantCulture));
        }
    }
}