2

I'm trying to fix memory spikes in a very large application. While I'm not sure how much of an effect this would have on memory, I noticed the following:

  • Application uses a custom thread pool to do all expensive tasks
  • Application will execute all incoming tasks
  • Tasks can be composed of thousands of sub tasks
  • While the thread pool will only execute {T} tasks at a time, and finishes a task completely before starting a new one, it does create a new system thread (Thread class) and start it for every sub task added to it
  • The sub task system threads are started with a thread start that instantly blocks on a manual reset event (MRE) pending a thread pool slot freeing up

So, this thread pool can create thousands of threads, but all but 30 (or whatever you configure) will be blocked on an MRE while other tasks complete.

My Question:


What impact on the memory/processor will a thousand threads blocked on MREs have? I don't have a lot of time to fix this spike, so if it's minimal, I'd rather leave the issue and work to fix it in a later patch when I have more time.

Also, is this behavior typical in thread pools, or does this sound flawed (I'm leaning towards flawed, but I don't have a good enough background to be sure).

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • 'Task Manager doesn't show them (I think it only shows active threads).' I hope not - my TM shows 1090 threads currently. – Martin James Mar 07 '13 at 17:27
  • I didn't mean threads running actively per se; I meant that I think it wouldn't show threads that aren't currently contending for the processor. If you create 500 threads in an app and put them all to sleep with MRE's will your app still have over 500 threads in task manager (honestly I'm not sure, but it doesn't appear so from what I'm seeing)? – John Humphreys Mar 07 '13 at 17:29
  • If your system creates new threads for every sub-task, it doesn't sound much like a 'pool'. – Martin James Mar 07 '13 at 17:29
  • I agree; bad legacy code. Never-the-less - do you have any idea how this affects the memory footprint and processor usage in the long term? – John Humphreys Mar 07 '13 at 17:30
  • @wOOte - yes. If I create 2000 threads and block them all, the TM shows my app has 2001 threads and 0% CPU use. – Martin James Mar 07 '13 at 17:31
  • Okay, I'm wrong about that then - I'll edit, and thanks for the info :) – John Humphreys Mar 07 '13 at 17:38

1 Answers1

3

What impact on the memory/processor will a thousand threads blocked on MREs have? I don't have a lot of time to fix this spike, so if it's minimal, I'd rather leave the issue and work to fix it in a later patch when I have more time.

Each thread, when created manually, has it's own stack allocated to it. By default, this will be 1MB per thread, though it is possible to make threads with a smaller stack via a constructor parameter.

You'd be much better off redesigning this, from the description of your problem, to use the standard ThreadPool, and a class like BlockingCollection<T> to handle your throttling. This is designed to directly allow bounding input, with blocking. Making a custom "thread pool" of an infinite number of threads is going to be far less efficient than using the highly tuned ThreadPool included with the framework.

Also, is this behavior typical in thread pools, or does this sound flawed (I'm leaning towards flawed, but I don't have a good enough background to be sure).

This is definitely flawed. The entire point of a ThreadPool is to avoid making a thread per request, and "pool" the threads (reusing them) for multiple requests without having to recreate them.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373