0

I'm writing a simple memory reporting utility (in this particular situation using an existing tool is not an option). I've got it to print the max, commit and usage for all the memory pools returned by iterating ManagementFactory.getMemoryPoolMXBeans(). That gets me the three heap generations of heap memory (eden, survivor and old), the permgen, and the "code cache".

None of these appear to be the method stack memory. The closest thing seems be the "code cache", but I've read that that's actually where the hotspotter puts compiled classes.

I ask because I'm trying to track down the cause of a crash in a JBoss webapp that's failing to create a new thread. http://www.mastertheboss.com/jboss-server/jboss-monitoring/how-to-solve-javalangoutofmemoryerror-unable-to-create-new-native-thread suggests that this could be due to running out of stack memory, which stands to reason. The question is: how do I get the stack memory, so I can check?

Len
  • 507
  • 5
  • 19
  • Stack memory is the same for every thread. This means your memory settings result in a limited number of threads you can have. You could monitor how many threads you currently have. – Thilo Nov 10 '14 at 00:42
  • @Thilo Wait, so every thread is allocated the full stack size at the time it is created? Even if most of that stack space is unused (few frames on the stack), all that memory is allocated and unavailable for the heap, permgen, the OS itself, etc? – Len Nov 10 '14 at 01:03
  • *"Stack memory"* is not a separate pool, it's just regular virtual memory. Either you've run out of virtual memory or hit the number of processes limit (`ulimit -u`). – apangin Nov 10 '14 at 01:08
  • The question remains "how much memory is the JVM using for thread stacks?" regardless of whether Java considers it a separate pool or not. – Len Nov 10 '14 at 01:42
  • Yes, every thread gets a same-sized stack and it is fully allocated when it is created. You can control it with `-Xss`. – Thilo Nov 10 '14 at 01:56
  • 3
    @Thilo Not all threads have the same stack size. A thread [can be constructed](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#Thread%28java.lang.ThreadGroup,%20java.lang.Runnable,%20java.lang.String,%20long%29) with a custom stack size. – apangin Nov 10 '14 at 13:54

1 Answers1

1

On Linux you can parse /proc/self/maps (or /proc/self/smaps for more details).
Look for the lines ending with [stack:NNN] and calculate the stack size as top - bottom:

7f8a5c0e1000-7f8a5c1df000 rw-p 00000000 00:00 0    [stack:2669]
^ bottom     ^ top                                        ^ tid

On Windows this would be harder, but you can estimate the memory used by stacks as
number_of_threads * default_stack_size

Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247