1

I have an application that makes heavy use of the Task Parallel Library. As my application runs, I notice that the number of threads reported being used by ProcessExplorer at times exceeds 200 threads for my application and eventually the application will lock when it runs out of threads.

When a I took a FULL DUMP of the memory using AdPlus and opened it in Visual Studio, I saw 82 threads running at that time (although ProcessExplorer reported over 100 at the time).

Many of those threads (42 of them) show only the following stack trace:

ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

My question is:

Are the threads with the above stack trace waiting for something that I kicked off and subsequently orphaned? Or does that stack trace just indicate an idle thread?

Ayo I
  • 7,722
  • 5
  • 30
  • 40
  • 2
    The stack trace indicates a thread, that is waiting for some kernel object. An orphaned kernel object would break out of the wait condition, so this is waiting for a live object. A thread that is in a wait state is synonymous for an idle thread. – IInspectable Sep 17 '15 at 18:41
  • Why is this a separate question from [your other one](http://stackoverflow.com/questions/32636148/why-do-some-native-threads-have-a-stack-trace-without-an-origin-in-my-code)? – theB Sep 17 '15 at 18:49
  • Because they're two separate questions. This question is whether or not the above stack trace indicates a thread blocked on work from my end, or simply an idle thread available to do work. The other question is to help me understand why the stack trace doesn't indicate a starting point in my managed code. – Ayo I Sep 17 '15 at 21:48
  • @IInspectable So the above is waiting for a kernel object? How can I figure out what object it's waiting for? So is this thread available to the TPL while it waits, or is it not available until the wait is satisfied? – Ayo I Sep 17 '15 at 21:51
  • The threads you're looking at are most likely either thread pool threads waiting for more work, or tasks waiting on the scheduler to allow them to start. As an aside, WinDbg can dig deeper into a memory dump than VS. (It just has a steep learning curve) – theB Sep 17 '15 at 22:35
  • If you need to know, how TPL is implemented, have a look at the [source](http://referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Parallel.cs). – IInspectable Sep 18 '15 at 00:52

1 Answers1

1

So it turns out that WinDbg really was the best way to get a definitive answer to the question of what all those threads are doing.

As theB statated, '_NtWaitForSingleObject@12 indicates that the thread is either idle waiting for work or waiting for the scheduler'

Using the !threadpool command in WinDbg, the following clearly indicates that these threads must be owned by the threadpool and that they are indeed idle:

0:073> !threadpool
CPU utilization: 21%
Worker Thread: Total: 256 Running: 2 Idle: 254 MaxLimit: 1023 MinLimit: 256
Work Request in Queue: 0
--------------------------------------
Number of Timers: 1
--------------------------------------
Completion Port Thread:Total: 1 Free: 1 MaxFree: 4 CurrentLimit: 1 MaxLimit: 1000 MinLimit: 256
Ayo I
  • 7,722
  • 5
  • 30
  • 40