/// <summary> /// Creates a buffer pool. /// </summary> /// <param name="bufferSize">The size, in bytes, of each buffer.</param> /// <param name="maxBuffers">The maximum number of buffers to keep around, unused; by default, the number of unused buffers is unbounded.</param> private BufferPool(int bufferSize, int maxBuffers, int preallocationSize, string name) { Name = name; byteBufferSize = bufferSize; maxBuffersCount = maxBuffers; limitBuffersCount = maxBuffers > 0; buffers = new ConcurrentBag <byte[]>(); var globalPoolSizeStat = IntValueStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_BUFFERS_INPOOL, () => Count); allocatedBufferCounter = CounterStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_ALLOCATED_BUFFERS); checkedOutBufferCounter = CounterStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_CHECKED_OUT_BUFFERS); checkedInBufferCounter = CounterStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_CHECKED_IN_BUFFERS); droppedBufferCounter = CounterStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_DROPPED_BUFFERS); droppedTooLargeBufferCounter = CounterStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_DROPPED_TOO_LARGE_BUFFERS); // Those 2 counters should be equal. If not, it means we don't release all buffers. IntValueStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_INUSE_CHECKED_OUT_NOT_CHECKED_IN_BUFFERS, () => checkedOutBufferCounter.GetCurrentValue() - checkedInBufferCounter.GetCurrentValue() - droppedBufferCounter.GetCurrentValue()); IntValueStatistic.FindOrCreate(StatisticNames.SERIALIZATION_BUFFERPOOL_INUSE_ALLOCATED_NOT_INPOOL_BUFFERS, () => allocatedBufferCounter.GetCurrentValue() - globalPoolSizeStat.GetCurrentValue() - droppedBufferCounter.GetCurrentValue()); if (preallocationSize <= 0) { return; } var dummy = GetMultiBuffer(preallocationSize * Size); Release(dummy); }
internal void Start() { if (!countersAvailable) { logger.Warn(ErrorCode.PerfCounterNotRegistered, "CPU & Memory perf counters did not initialize correctly - try repairing Windows perf counter config on this machine with 'lodctr /r' command"); return; } cpuUsageTimer = new SafeTimer(CheckCpuUsage, null, CPU_CHECK_PERIOD, CPU_CHECK_PERIOD); try { // Read initial value of CPU Usage counter CpuUsage = cpuCounter.NextValue(); } catch (InvalidOperationException) { // Can sometimes get exception accessing CPU Usage counter for first time in some runtime environments CpuUsage = 0; } FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_CPUUSAGE, () => CpuUsage); IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_TOTALMEMORYKB, () => (MemoryUsage + 1023) / 1024); // Round up #if LOG_MEMORY_PERF_COUNTERS // print GC stats in the silo log file. StringValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_GENCOLLECTIONCOUNT, () => GCGenCollectionCount); StringValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_GENSIZESKB, () => GCGenSizes); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PERCENTOFTIMEINGC, () => timeInGC.NextValue()); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_ALLOCATEDBYTESINKBPERSEC, () => allocatedBytesPerSec.NextValue() / 1024f); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PROMOTEDMEMORYFROMGEN1KB, () => promotedMemoryFromGen1.NextValue() / 1024f); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_LARGEOBJECTHEAPSIZEKB, () => largeObjectHeapSize.NextValue() / 11024f); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_PROMOTEDMEMORYFROMGEN0KB, () => promotedFinalizationMemoryFromGen0.NextValue() / 1024f); FloatValueStatistic.FindOrCreate(StatisticNames.RUNTIME_GC_NUMBEROFINDUCEDGCS, () => numberOfInducedGCs.NextValue()); IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_MEMORY_TOTALPHYSICALMEMORYMB, () => (TotalPhysicalMemory / 1024) / 1024); if (availableMemoryCounter != null) { IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_MEMORY_AVAILABLEMEMORYMB, () => (AvailableMemory / 1024) / 1024); // Round up } #endif IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_WORKERTHREADS, () => { int maXworkerThreads; int maXcompletionPortThreads; ThreadPool.GetMaxThreads(out maXworkerThreads, out maXcompletionPortThreads); int workerThreads; int completionPortThreads; // GetAvailableThreads Retrieves the difference between the maximum number of thread pool threads // and the number currently active. // So max-Available is the actual number in use. If it goes beyond min, it means we are stressing the thread pool. ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads); return(maXworkerThreads - workerThreads); }); IntValueStatistic.FindOrCreate(StatisticNames.RUNTIME_DOT_NET_THREADPOOL_INUSE_COMPLETIONPORTTHREADS, () => { int maXworkerThreads; int maXcompletionPortThreads; ThreadPool.GetMaxThreads(out maXworkerThreads, out maXcompletionPortThreads); int workerThreads; int completionPortThreads; ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads); return(maXcompletionPortThreads - completionPortThreads); }); }