Skip to content

Commit de9f376

Browse files
committed
Align counters
1 parent 4c8621a commit de9f376

File tree

1 file changed

+59
-59
lines changed

1 file changed

+59
-59
lines changed

docs/core/diagnostics/debug-threadpool-starvation.md

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -97,45 +97,45 @@ dotnet-counters monitor -n DiagnosticScenarios
9797
Press p to pause, r to resume, q to quit.
9898
Status: Running
9999
100-
Name Current Value
100+
Name Current Value
101101
[System.Runtime]
102-
dotnet.assembly.count ({assembly}) 115
102+
dotnet.assembly.count ({assembly}) 115
103103
dotnet.gc.collections ({collection})
104104
gc.heap.generation
105-
gen0 2
106-
gen1 1
107-
gen2 1
108-
dotnet.gc.heap.total_allocated (By) 64,329,632
105+
gen0 2
106+
gen1 1
107+
gen2 1
108+
dotnet.gc.heap.total_allocated (By) 64,329,632
109109
dotnet.gc.last_collection.heap.fragmentation.size (By)
110110
gc.heap.generation
111-
gen0 199,920
112-
gen1 29,208
113-
gen2 0
114-
loh 32
115-
poh 0
111+
gen0 199,920
112+
gen1 29,208
113+
gen2 0
114+
loh 32
115+
poh 0
116116
dotnet.gc.last_collection.heap.size (By)
117117
gc.heap.generation
118-
gen0 208,712
119-
gen1 3,456,000
120-
gen2 5,065,600
121-
loh 98,384
122-
poh 3,147,488
123-
dotnet.gc.last_collection.memory.committed_size (By) 31,096,832
124-
dotnet.gc.pause.time (s) 0.024
125-
dotnet.jit.compilation.time (s) 1.285
126-
dotnet.jit.compiled_il.size (By) 565,249
127-
dotnet.jit.compiled_methods ({method}) 5,831
128-
dotnet.monitor.lock_contentions ({contention}) 148
129-
dotnet.process.cpu.count ({cpu}) 16
118+
gen0 208,712
119+
gen1 3,456,000
120+
gen2 5,065,600
121+
loh 98,384
122+
poh 3,147,488
123+
dotnet.gc.last_collection.memory.committed_size (By) 31,096,832
124+
dotnet.gc.pause.time (s) 0.024
125+
dotnet.jit.compilation.time (s) 1.285
126+
dotnet.jit.compiled_il.size (By) 565,249
127+
dotnet.jit.compiled_methods ({method}) 5,831
128+
dotnet.monitor.lock_contentions ({contention}) 148
129+
dotnet.process.cpu.count ({cpu}) 16
130130
dotnet.process.cpu.time (s)
131131
cpu.mode
132-
system 2.156
133-
user 2.734
134-
dotnet.process.memory.working_set (By) 1.3217e+08
135-
dotnet.thread_pool.queue.length ({work_item}) 0
136-
dotnet.thread_pool.thread.count ({thread}) 0
137-
dotnet.thread_pool.work_item.count ({work_item}) 32,267
138-
dotnet.timer.count ({timer}) 0
132+
system 2.156
133+
user 2.734
134+
dotnet.process.memory.working_set (By) 1.3217e+08
135+
dotnet.thread_pool.queue.length ({work_item}) 0
136+
dotnet.thread_pool.thread.count ({thread}) 0
137+
dotnet.thread_pool.work_item.count ({work_item}) 32,267
138+
dotnet.timer.count ({timer}) 0
139139
```
140140

141141
The counters above are an example while the web server wasn't serving any requests. Run Bombardier again with the `api/diagscenario/tasksleepwait` endpoint and sustained load for 2 minutes so there's plenty of time to observe what happens to the performance counters.
@@ -148,43 +148,43 @@ ThreadPool starvation occurs when there are no free threads to handle the queued
148148

149149
```dotnetcli
150150
[System.Runtime]
151-
dotnet.assembly.count ({assembly}) 115
151+
dotnet.assembly.count ({assembly}) 115
152152
dotnet.gc.collections ({collection})
153153
gc.heap.generation
154-
gen0 5
155-
gen1 1
156-
gen2 1
157-
dotnet.gc.heap.total_allocated (By) 1.6947e+08
154+
gen0 5
155+
gen1 1
156+
gen2 1
157+
dotnet.gc.heap.total_allocated (By) 1.6947e+08
158158
dotnet.gc.last_collection.heap.fragmentation.size (By)
159159
gc.heap.generation
160-
gen0 0
161-
gen1 348,248
162-
gen2 0
163-
loh 32
164-
poh 0
160+
gen0 0
161+
gen1 348,248
162+
gen2 0
163+
loh 32
164+
poh 0
165165
dotnet.gc.last_collection.heap.size (By)
166166
gc.heap.generation
167-
gen0 0
168-
gen1 18,010,920
169-
gen2 5,065,600
170-
loh 98,384
171-
poh 3,407,048
172-
dotnet.gc.last_collection.memory.committed_size (By) 66,842,624
173-
dotnet.gc.pause.time (s) 0.05
174-
dotnet.jit.compilation.time (s) 1.317
175-
dotnet.jit.compiled_il.size (By) 574,886
176-
dotnet.jit.compiled_methods ({method}) 6,008
177-
dotnet.monitor.lock_contentions ({contention}) 194
178-
dotnet.process.cpu.count ({cpu}) 16
167+
gen0 0
168+
gen1 18,010,920
169+
gen2 5,065,600
170+
loh 98,384
171+
poh 3,407,048
172+
dotnet.gc.last_collection.memory.committed_size (By) 66,842,624
173+
dotnet.gc.pause.time (s) 0.05
174+
dotnet.jit.compilation.time (s) 1.317
175+
dotnet.jit.compiled_il.size (By) 574,886
176+
dotnet.jit.compiled_methods ({method}) 6,008
177+
dotnet.monitor.lock_contentions ({contention}) 194
178+
dotnet.process.cpu.count ({cpu}) 16
179179
dotnet.process.cpu.time (s)
180180
cpu.mode
181-
system 4.953
182-
user 6.266
183-
dotnet.process.memory.working_set (By) 1.3217e+08
184-
dotnet.thread_pool.queue.length ({work_item}) 0
185-
dotnet.thread_pool.thread.count ({thread}) 133
186-
dotnet.thread_pool.work_item.count ({work_item}) 71,188
187-
dotnet.timer.count ({timer}) 124
181+
system 4.953
182+
user 6.266
183+
dotnet.process.memory.working_set (By) 1.3217e+08
184+
dotnet.thread_pool.queue.length ({work_item}) 0
185+
dotnet.thread_pool.thread.count ({thread}) 133
186+
dotnet.thread_pool.work_item.count ({work_item}) 71,188
187+
dotnet.timer.count ({timer}) 124
188188
```
189189

190190
Once the count of ThreadPool threads stabilizes, the pool is no longer starving. But if it stabilizes at a high value (more than about three times the number of processor cores), that usually indicates the application code is blocking some ThreadPool threads and the ThreadPool is compensating by running with more threads. Running steady at high thread counts won't necessarily have large impacts on request latency, but if load varies dramatically over time or the app will be periodically restarted, then each time the ThreadPool is likely to enter a period of starvation where it's slowly increasing threads and delivering poor request latency. Each thread also consumes memory, so reducing the total number of threads needed provides another benefit.

0 commit comments

Comments
 (0)