2

As I was studying about threads and the memory they consume (thread stack), I decided to do a simple load test to see how does number of threads affects RAM on my computer.

So, for the test I used Tomcat, and in the settings.xml set minimal and maximal web container thread pool to 200. After that I did the same while setting pool to 2000. I was shocked 'cause there was no difference in memory occupation (was checking through Windows Task Manger) and it was almost the same. So I thought maybe those threads have to be in the running state, used a load test tool to "bombard" the server and I've managed to do some heavy load, most of the threads were now in the running state but there was no change in the memory consumption between 200 and 2000 threads.

So I'm wondering what is this thread's stack memory all about and does these results mean that memory on the thread stack isn't allocated while the thread is created? How would I be able to simulate thread stack memory growth to the size where a difference in RAM consumption is seen to a "naked eye" on the graphs?

Thanks in advance!

localhost
  • 226
  • 5
  • 11
  • Instead of Window's Task Manger, [profile](http://stackoverflow.com/q/2064427/230513) for more detail. – trashgod Oct 27 '14 at 10:43
  • Do you want to monitor impact of threads on memory or impact of stack size? For stack size impact it's easier to create a big stack with a recursive method. Maybe you'll find some clues here : http://stackoverflow.com/questions/10629521/confused-with-java-memory-management-stacks-and-heaps – nomoa Oct 27 '14 at 10:47
  • Impact of threads on memory is a concerne. I guess that "blank" even while running don't use any memory? – localhost Oct 27 '14 at 10:53
  • Details depends on the OS, but this question has already been somewhat answered here : http://stackoverflow.com/questions/5483047/why-is-creating-a-thread-said-to-be-expensive – nomoa Oct 27 '14 at 10:58
  • Another interesting answer : http://stackoverflow.com/questions/20030120/java-default-stack-size – nomoa Oct 27 '14 at 11:10
  • Thread stacks are paged, so if you don't use much of the available stack, not much of the stacks will be loaded into RAM. – Martin James Oct 27 '14 at 11:38

1 Answers1

2

Thread stacks are allocated in the native memory (not in the Java heap), the default stack size is between 256 k and 1 M (depending on OS and whether the JVM is 32 or 64-bit), you can control it with the -Xss JVM option. If you run out of stack memory, you get the "java.lang.OutOfMemoryError: unable to create new native thread" error.

If you want to track the stack memory usage on Windows on the OS level, use VMMap instead of Task Manager, because it shows you the stack memory.

You can also track the stack memory usage within Java if you have a recent JDK with -XX:NativeMemoryTracking and jcmd, the details are here.

I don't know what is wrong with your test, I suggest to put a Thread.sleep in your code to make sure that all threads are running.

lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • 2
    Well, after some more testing I found out that when you create a thread it doesn't take default stack size (from 256k to 1M) from a native memory, it takes almost nothing. So the Xss JVM param is about MAXIMUM stack size in memory per thread, not initial on creation. Therefore creating 10 or 1000 threads doesn't make alot difference looking from a memory perspective. – localhost Oct 28 '14 at 09:51
  • Yes, in vmmap you can see that initially a large part of the thread stack memory is only "reserved". Anyway, in a real life app sooner or later you would need to allocate the whole stack memory, so running thousands of threads is still a big deal. – lbalazscs Oct 28 '14 at 14:15
  • Also see this: http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx – lbalazscs Oct 28 '14 at 14:25
  • It's a great article, thanks. Moreover, when you say that in a real life app sooner or later you allocate the whole stack memory.. Well, I really dont' see how. In threads stack you save function params, method calls, thread state and that's all ligtweight and is measured in kilobytes, so I guess a difference between 10 or 1000 threads can be tens of MB which is not such a big improvement? Am I missing something? – localhost Oct 28 '14 at 14:50
  • Ok, not the whole maximal stack, but a lot more than in simple test programs. BTW, on my 4 GB RAM, 64 bit machine, I just managed to start 50 000 simple threads, but the machine became really unresponsive :) Anyway, this is not important, as the article says, if you need thousands of threads, your design is flawed, and you should rewrite it to use asynchronous IO (in Java NIO) – lbalazscs Oct 28 '14 at 15:04