{"id":54159,"date":"2025-11-25T03:55:53","date_gmt":"2025-11-25T03:55:53","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=54159"},"modified":"2026-02-21T08:29:04","modified_gmt":"2026-02-21T08:29:04","slug":"dotnet-counters-demo-lab","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/dotnet-counters-demo-lab\/","title":{"rendered":"dotnet-counters: Demo &amp; Lab"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">1. What this screen is showing<\/h2>\n\n\n\n<p>How to install?<\/p>\n\n\n\n<p>$ dotnet tool install &#8211;global dotnet-counters<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"387\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26-1024x387.png\" alt=\"\" class=\"wp-image-54162\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26-1024x387.png 1024w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26-300x113.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26-768x290.png 768w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26-1536x580.png 1536w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2025\/11\/image-26.png 1909w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Your command:<\/p>\n\n\n\n<p>$ dotnet-counters ps<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">$ dotnet-counters monitor -p 30420 System.Runtime Microsoft.AspNetCore.Hosting Microsoft-AspNetCore-Server-Kestrel Microsoft.AspNetCore.Http.Connections System.Net.Http Microsoft.EntityFrameworkCore\n<\/code><\/span><\/pre>\n\n\n<p>And the section you pasted is only the <strong>[System.Runtime]<\/strong> provider \u2013 i.e. <strong>core .NET runtime health<\/strong>.<\/p>\n\n\n\n<p>This is the \u201cvitals panel\u201d of the CLR:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CPU<\/li>\n\n\n\n<li>GC<\/li>\n\n\n\n<li>JIT<\/li>\n\n\n\n<li>ThreadPool<\/li>\n\n\n\n<li>Memory usage<\/li>\n<\/ul>\n\n\n\n<p>And right now the numbers show a <strong>mostly idle app<\/strong> (no meaningful load).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">2. Key metrics in your output (with meaning)<\/h2>\n\n\n\n<p>I\u2019ll go through the most important ones and tell you how to explain them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 CPU Usage (%)<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">CPU<\/span> <span class=\"hljs-selector-tag\">Usage<\/span> (%)  0<span class=\"hljs-selector-class\">.198<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>How to say it: \u201cOverall process CPU usage as seen by the .NET runtime.\u201d<\/li>\n\n\n\n<li>Here it\u2019s ~0.2%, so the app is basically idle.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 Allocation Rate (B \/ 1 sec)<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Allocation Rate (B \/ 1 sec)  16,400\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>New managed memory allocated per second on the managed heap.<\/li>\n\n\n\n<li>Under real load, this can be <strong>MB\/sec or GB\/sec<\/strong>.<\/li>\n\n\n\n<li>For your <em>naive vs optimized<\/em> demo:\n<ul class=\"wp-block-list\">\n<li>Naive code \u2192 <strong>higher allocation rate<\/strong> (lots of short-lived objects)<\/li>\n\n\n\n<li>Optimized \u2192 lower allocation rate \u2192 less GC pressure.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 GC Heap Size (MB) &amp; GC Committed Bytes (MB)<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">GC<\/span> <span class=\"hljs-selector-tag\">Heap<\/span> <span class=\"hljs-selector-tag\">Size<\/span> (<span class=\"hljs-selector-tag\">MB<\/span>)         3<span class=\"hljs-selector-class\">.192<\/span>\n<span class=\"hljs-selector-tag\">GC<\/span> <span class=\"hljs-selector-tag\">Committed<\/span> <span class=\"hljs-selector-tag\">Bytes<\/span> (<span class=\"hljs-selector-tag\">MB<\/span>)  10<span class=\"hljs-selector-class\">.277<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GC Heap Size<\/strong>: How much managed heap is currently in use.<\/li>\n\n\n\n<li><strong>GC Committed Bytes<\/strong>: Total memory the GC has reserved\/committed from the OS.<\/li>\n\n\n\n<li>Story for slides:\n<ul class=\"wp-block-list\">\n<li>\u201cIf Heap Size keeps growing and never comes down, we may have a memory leak or a workload that allocates a lot and doesn\u2019t release.\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 % Time in GC &amp; Time paused by GC<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">% Time in GC since last GC (%)   0\nTime paused by GC (ms \/ 1 sec)   0\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><code>% Time in GC<\/code>: Fraction of time the runtime is doing GC work.<\/li>\n\n\n\n<li><code>Time paused by GC<\/code>: Time the app is <strong>stopped<\/strong> for GC per second.<\/li>\n\n\n\n<li>Under heavy allocation:\n<ul class=\"wp-block-list\">\n<li>High <code>% Time in GC<\/code> and non-zero <code>Time paused by GC<\/code> \u2192 GC is impacting throughput \/ latency.<\/li>\n\n\n\n<li>In your demo you could show:<br>\u201cNaive bulk insert \u2192 higher % time in GC; optimized version \u2192 less.\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 Gen 0 \/ Gen 1 \/ Gen 2 counts &amp; sizes<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Gen 0 GC Count (Count \/ 1 sec)  0\nGen 0 Size (B)                  646,848\n\nGen 1 GC Count (Count \/ 1 sec)  0\nGen 1 Size (B)                  832\n\nGen 2 GC Count (Count \/ 1 sec)  0\nGen 2 Size (B)                  1,989,064\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Gen 0\/1\/2 <strong>Sizes<\/strong>: How much of each generation is currently occupied.<\/li>\n\n\n\n<li>Gen 0\/1\/2 <strong>GC Count (\/sec)<\/strong>: How often GC runs for each generation.<\/li>\n\n\n\n<li>How to narrate:\n<ul class=\"wp-block-list\">\n<li>\u201cGen 0 is for short-lived objects; Gen 2 is long-lived (e.g., caches, static data).\u201d<\/li>\n\n\n\n<li>\u201cToo many Gen 2 collections \u2192 expensive, can cause noticeable pauses.\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>For an idle app, counts\/sec = 0 is normal.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 LOH Size &amp; POH Size<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">LOH Size (B)        98,384\nPOH Size (B)       130,680\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>LOH (Large Object Heap)<\/strong>: Objects \u2265 85 KB (arrays, big strings, etc.).<\/li>\n\n\n\n<li><strong>POH (Pinned Object Heap)<\/strong>: Objects that can\u2019t be moved (e.g. for interop).<\/li>\n\n\n\n<li>Slide point:\n<ul class=\"wp-block-list\">\n<li>\u201cLarge or pinned heaps that keep growing can cause memory fragmentation and larger GCs.\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 Monitor Lock Contention Count<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Monitor Lock Contention Count (Count \/ 1 sec)  0\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Number of times threads block waiting for <code>lock<\/code>\/<code>Monitor.Enter<\/code>.<\/li>\n\n\n\n<li>Under contention, this will be non-zero.<\/li>\n\n\n\n<li>Good line for your talk: \u201cIf this counter spikes during load, we\u2019re likely hitting lock contention \u2013 too many threads fighting for the same lock.\u201d<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 ThreadPool metrics<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">ThreadPool Completed Work Item Count (Count \/ 1 sec)  0\nThreadPool Queue Length                              0\nThreadPool Thread Count                              0\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Completed Work Item Count<\/strong>: How many ThreadPool tasks are completing per second.<\/li>\n\n\n\n<li><strong>Queue Length<\/strong>: Pending work items waiting for threads.<\/li>\n\n\n\n<li><strong>Thread Count<\/strong>: Number of ThreadPool threads (this being 0 is likely a momentary state; usually you\u2019ll see &gt; 1 when load comes in).<\/li>\n<\/ul>\n\n\n\n<p>What to say:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cIf Queue Length grows but Thread Count doesn\u2019t grow fast enough, we have ThreadPool starvation.\u201d<\/li>\n\n\n\n<li>\u201cUnder load, we expect some reasonable thread count and completed work items\/sec.\u201d<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 JIT metrics<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">IL Bytes Jitted (B)           <span class=\"hljs-number\">528<\/span>,<span class=\"hljs-number\">863<\/span>\n<span class=\"hljs-built_in\">Number<\/span> <span class=\"hljs-keyword\">of<\/span> Methods Jitted      <span class=\"hljs-number\">6<\/span>,<span class=\"hljs-number\">639<\/span>\nTime spent <span class=\"hljs-keyword\">in<\/span> JIT (ms \/ <span class=\"hljs-number\">1<\/span> sec) <span class=\"hljs-number\">0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><strong>IL Bytes Jitted \/ Methods Jitted<\/strong>: Total IL compiled to machine code.<\/li>\n\n\n\n<li><strong>Time spent in JIT<\/strong>: JIT cost per second.<\/li>\n\n\n\n<li>Early after startup:\n<ul class=\"wp-block-list\">\n<li>These numbers grow quickly.<\/li>\n\n\n\n<li>Later they flatten once code is \u201cwarmed up.\u201d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Slide story: \u201cJIT happens mostly at startup and first-time execution; after that the cost should be negligible.\u201d<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 Working Set (MB)<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Working <span class=\"hljs-built_in\">Set<\/span> (MB)  <span class=\"hljs-number\">106.906<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Total physical memory in use by the process (managed + native).<\/li>\n\n\n\n<li>Use it to show overall footprint.<\/li>\n\n\n\n<li>In your story:\n<ul class=\"wp-block-list\">\n<li>\u201cNaive version might cause working set to grow more due to excessive allocations or caching.\u201d<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 Assemblies Loaded &amp; Active Timers<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">Number<\/span> <span class=\"hljs-keyword\">of<\/span> Assemblies Loaded  <span class=\"hljs-number\">137<\/span>\n<span class=\"hljs-built_in\">Number<\/span> <span class=\"hljs-keyword\">of<\/span> Active Timers      <span class=\"hljs-number\">2<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Assemblies loaded \u2192 footprint of the app\u2019s codebase.<\/li>\n\n\n\n<li>Active Timers \u2192 number of timers scheduled (e.g., background jobs, periodic tasks).<\/li>\n<\/ul>\n\n\n\n<p>Not usually your first troubleshooting metric, but nice context.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">3. How to use this in <strong>training\/demo<\/strong><\/h2>\n\n\n\n<p>For your perf engineering session, you can say:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cThis is our <strong>baseline view<\/strong> with <code>System.Runtime<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CPU is ~0% \u2192 our app is idle.<\/li>\n\n\n\n<li>Allocation rate is tiny, GC time is 0 \u2192 no GC pressure.<\/li>\n\n\n\n<li>Heap is ~3 MB, working set ~107 MB \u2192 small footprint.<\/li>\n<\/ul>\n\n\n\n<p>Now let\u2019s send load and watch:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CPU Usage<\/li>\n\n\n\n<li>Allocation Rate<\/li>\n\n\n\n<li>% Time in GC \/ Time paused by GC<\/li>\n\n\n\n<li>ThreadPool Queue Length<\/li>\n\n\n\n<li>Working Set (MB)<\/li>\n<\/ul>\n\n\n\n<p>and compare <strong>naive vs optimized<\/strong> implementation.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p>If you\u2019d like, next I can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Take these exact counters and write <strong>2\u20133 slide pages<\/strong>:\n<ul class=\"wp-block-list\">\n<li>\u201cTop 8 System.Runtime counters every .NET engineer should know\u201d<\/li>\n\n\n\n<li>Each with 1-line explanation + \u201cHow to interpret when it\u2019s high\u201d.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">CREATE LOAD<\/h2>\n\n\n\n<p>$ curl -k -X POST &#8220;https:\/\/localhost:5001\/api\/orders\/bulk-optimized?count=100000&#8221;<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<p>Nice, <strong>now we\u2019re seeing real activity<\/strong> \u2013 this is exactly the kind of snapshot you want to show in your perf session as \u201capp under load\u201d.<\/p>\n\n\n\n<p>Let\u2019s decode it in a focused way and then I\u2019ll give you <strong>slide-ready talking points<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">1\ufe0f\u20e3 What changed vs earlier (idle) snapshot?<\/h2>\n\n\n\n<p>Earlier:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Allocation Rate: ~16 KB\/sec<\/li>\n\n\n\n<li>GC Heap Size: ~3 MB<\/li>\n\n\n\n<li>Working Set: ~107 MB<\/li>\n\n\n\n<li>CPU: ~0.2%<\/li>\n<\/ul>\n\n\n\n<p>Now:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Allocation Rate (B \/ 1 sec)   50,067,464   \u2248 50 MB\/sec\nCPU Usage (%)                  5.159\nGC Heap Size (MB)            239.699\nGC Committed Bytes (MB)      361.464\nWorking Set (MB)             491.52\nGen 2 Size (B)               1.1923e+08 \u2248 113.7 MB\nLOH Size (B)                 27,713,016 \u2248 26.4 MB\nThreadPool Thread Count      6\nThreadPool Completed Work\n    Item Count (\/sec)        609\nMonitor Lock Contention\n    Count (\/sec)             2\nTime spent in JIT (ms\/sec)   12.602\n<\/code><\/span><\/pre>\n\n\n<p><strong>Story in one line:<\/strong><br>\ud83d\udc49 <em>\u201cUnder load, the app is allocating ~50 MB\/sec, heap has grown to ~240 MB, working set to ~490 MB, some JIT work still happening, and the ThreadPool is actively processing ~600 work items\/sec with a little lock contention.\u201d<\/em><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">2\ufe0f\u20e3 Key counters &amp; how to interpret them<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\ude80 Allocation Rate \u2013 <strong>50 MB\/sec<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This is <strong>very high<\/strong> compared to your idle state.<\/li>\n\n\n\n<li>Great demo point:<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cOur workload allocates ~50 MB of managed objects every second. If this stays high, GC will eventually need to work harder, potentially increasing GC pauses.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p>For <strong>naive implementation<\/strong> you\u2019d expect:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Higher allocation rate<\/li>\n\n\n\n<li>More frequent GCs later<\/li>\n\n\n\n<li>Possible % Time in GC and Time paused by GC increasing when pressure rises<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\udde0 Heap &amp; Memory Footprint<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">GC Heap Size (MB)       \u2248 <span class=\"hljs-number\">240<\/span> MB\nGC Committed Bytes (MB) \u2248 <span class=\"hljs-number\">361<\/span> MB\nWorking <span class=\"hljs-built_in\">Set<\/span> (MB)        \u2248 <span class=\"hljs-number\">492<\/span> MB\nGen <span class=\"hljs-number\">2<\/span> Size              \u2248 <span class=\"hljs-number\">114<\/span> MB\nLOH Size                \u2248 <span class=\"hljs-number\">26<\/span> MB\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Points:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cThe <strong>managed heap<\/strong> alone is about 240 MB now.\u201d<\/li>\n\n\n\n<li>\u201cThe GC has reserved ~360 MB from the OS to manage this heap.\u201d<\/li>\n\n\n\n<li>\u201cTotal <strong>working set<\/strong> (managed + native) is about 490 MB.\u201d<\/li>\n\n\n\n<li>\u201cA big part of memory is in <strong>Gen 2<\/strong> (long-lived objects, ~114 MB) and some in <strong>LOH<\/strong> (~26 MB, large arrays\/buffers).\u201d<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cIf GC Heap Size and Gen 2 Size keep growing and rarely shrink, we may be trending toward a memory leak or a very heavy long-lived cache.\u201d<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\u23f1 GC &amp; Pauses<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">% Time in GC (%)         0\nTime paused by GC (ms\/s) 0\nGen 0 \/ Gen 1 \/ Gen 2\n    GC Count (\/sec)      0\n<\/code><\/span><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Despite high allocations, at the moment of this sample:\n<ul class=\"wp-block-list\">\n<li>No collections in that 1-second window.<\/li>\n\n\n\n<li>No GC pause time in that exact second.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Important nuance:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cThis is a 1-second snapshot. We\u2019re seeing high allocations, but GC didn\u2019t happen <em>in this particular second<\/em>. Over time, we\u2019d expect this to eventually trigger GCs; when that happens, <code>% Time in GC<\/code> and <code>Time paused by GC<\/code> will start to show non-zero values.\u201d<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\uddf5 ThreadPool &amp; Concurrency<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">ThreadPool Thread Count                 6\nThreadPool Completed Work Item (\/sec)  609\nThreadPool Queue Length                 0\nMonitor Lock Contention Count (\/sec)    2\n<\/code><\/span><\/pre>\n\n\n<p>How to narrate:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u201cWe have 6 ThreadPool threads currently handling ~600 work items per second.\u201d<\/li>\n\n\n\n<li>\u201cQueue length is 0 \u2192 threads are keeping up with the load.\u201d<\/li>\n\n\n\n<li>\u201cLock contention count is 2\/sec \u2192 a <strong>small<\/strong> but non-zero sign that some threads occasionally wait on locks.\u201d<\/li>\n<\/ul>\n\n\n\n<p>In a problematic scenario you\u2019d see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>High Queue Length<\/strong> + low Thread Count \u2192 ThreadPool starvation.<\/li>\n\n\n\n<li>High Lock Contention Count\/sec \u2192 contention on <code>lock<\/code>\/critical sections.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83e\udde9 JIT Activity<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">IL Bytes Jitted (B)      \u2248 <span class=\"hljs-number\">1.2<\/span> MB\n<span class=\"hljs-built_in\">Number<\/span> <span class=\"hljs-keyword\">of<\/span> Methods Jitted <span class=\"hljs-number\">15<\/span>,<span class=\"hljs-number\">635<\/span>\nTime spent <span class=\"hljs-keyword\">in<\/span> JIT (ms\/s) <span class=\"hljs-number\">12.602<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Still some JIT happening (12.6 ms\/sec).<\/li>\n\n\n\n<li>You can say:<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cAs the workload exercises more code paths, we see JIT still compiling methods. Once warm, <code>Time spent in JIT<\/code> should drop close to 0.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p>Useful to highlight \u201cwarm-up\u201d behavior vs \u201csteady state\u201d.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">3\ufe0f\u20e3 summary <\/h2>\n\n\n\n<p><strong>Title: Example \u2013 System.Runtime under Load<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CPU Usage<\/strong>: ~5% \u2013 app is doing real work but not CPU-bound yet.<\/li>\n\n\n\n<li><strong>Allocation Rate<\/strong>: ~50 MB\/sec \u2013 high allocation pressure; GC will need to work harder as load continues.<\/li>\n\n\n\n<li><strong>GC Heap Size<\/strong>: ~240 MB; <strong>GC Committed<\/strong>: ~360 MB \u2013 significant managed memory footprint.<\/li>\n\n\n\n<li><strong>Gen 2 &amp; LOH<\/strong>: ~114 MB (Gen 2), ~26 MB (LOH) \u2013 many long-lived \/ large objects.<\/li>\n\n\n\n<li><strong>GC Time \/ Pauses<\/strong>: 0% and 0 ms in this snapshot \u2013 no GC happening in this particular second.<\/li>\n\n\n\n<li><strong>ThreadPool<\/strong>: 6 threads, ~600 work items\/sec, queue length 0 \u2013 threads are keeping up with request load.<\/li>\n\n\n\n<li><strong>Lock Contention<\/strong>: 2\/sec \u2013 minor contention, not yet alarming.<\/li>\n\n\n\n<li><strong>Working Set<\/strong>: ~490 MB \u2013 overall process memory usage.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cThis snapshot shows our app under load: high allocation rate, large heap and working set, active ThreadPool, and some lock contention. Right now GC isn\u2019t pausing us, but if we keep allocating at ~50 MB\/sec, we will eventually see more GC activity and potential pauses.\u201d<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What this screen is showing How to install? $ dotnet tool install &#8211;global dotnet-counters Your command: $ dotnet-counters ps And the section you pasted is only the [System.Runtime] provider&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[11138],"tags":[],"class_list":["post-54159","post","type-post","status-publish","format-standard","hentry","category-best-tools"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/54159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=54159"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/54159\/revisions"}],"predecessor-version":[{"id":59882,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/54159\/revisions\/59882"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=54159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=54159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=54159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}