87

I understand that each thread has its own stack. Primitive types and references are kept on the stack, and that no object is kept on the stack.

My questions are:

  • How much can a stack grow? (like with the paramters -Xms and -Xmx)
  • Can we limit its growth?
  • Does the stack have a default minimum value and maximum value?
  • How does garbage collection work on the stack?
Hearen
  • 7,420
  • 4
  • 53
  • 63
codingenious
  • 8,385
  • 12
  • 60
  • 90
  • just a little remark for people reading this: Escape-Analysis (Java 6 Update 21 and above) allows to store objects in stack. Less work for garbage collector. – miracle_the_V Oct 27 '15 at 11:43
  • Partial dup of http://stackoverflow.com/questions/6020619/where-to-find-default-xss-value-for-sun-oracle-jvm – Vadzim Nov 21 '16 at 16:14
  • GC doesn't work on the stack. You cannot create things on the stack thus there is nothing to collect - JVM itself puts stuff into stack and removes it as necessary. "Garbage" that is collected are instances of your objects you've created. – mvmn May 08 '20 at 15:54

2 Answers2

100

How much a stack can grow?

You can use a VM option named ss to adjust the maximum stack size. A VM option is usually passed using -X{option}. So you can use java -Xss1M to set the maximum of stack size to 1M.

Each thread has at least one stack. Some Java Virtual Machines (JVM) put Java stack (Java method calls) and native stack (Native method calls in VM) into one stack, and perform stack unwinding using a "Managed to Native Frame", known as M2nFrame. Some JVMs keep two stacks separately. The Xss set the size of the Java Stack in most cases.

For many JVMs, they put different default values for stack size on different platforms.


Can we limit this growth?

When a method call occurs, a new stack frame will be created on the stack of that thread. The stack will contain local variables, parameters, return address, etc. In Java, you can never put an object on stack, only object reference can be stored on stack. Since array is also an object in Java, arrays are also not stored on stack. So, if you reduce the amount of your local primitive variables, parameters by grouping them into objects, you can reduce the space on stack. Actually, the fact that we cannot explicitly put objects on Java stack affects the performance some time (cache miss).


Does stack has some default minimum value or default maximum value?

As I said before, different VMs are different, and may change over versions. See here.


How does garbage collection work on stack?

Garbage collections in Java is a hot topic. Garbage collection aims to collect unreachable objects in the heap. So that needs a definition of 'reachable.' Everything on the stack constitutes part of the root set references in GC. Everything that is reachable from every stack of every thread should be considered as live. There are some other root set references, like Thread objects and some class objects.

This is only a very vague use of stack on GC. Currently most JVMs are using a generational GC. This article gives brief introduction about Java GC. And recently I read a very good article talking about the GC on .NET platform. The GC on Oracle JVM is quite similar so I think that might also help you.

informatik01
  • 16,038
  • 10
  • 74
  • 104
StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • 5
    Good answer. I'd just like to add that I find the defaults conservative, and they are meant to cover all kinds of deployments. But in my experience, even with large applications (over 500k lines of code) running in application servers, I've never had a StackOverflow error even with the stack set to 256k (-Xss256k). Consider an app server with 70 running threads, with the default 1MB stack, that's an additional 70MB for the process. – brettw Nov 17 '13 at 13:43
  • 7
    `java -Xss 100M -jar testing.jar` threw an error of "Invalid thread stack size: -Xss Error: Could not create Java Virtual Machine." but `java -Xss100M -jar testing.jar` worked just fine. Running Windows 10 64-bit with Java "1.8.0_112". Should your post be edited to remove the space? – Aaron Franke Dec 27 '16 at 06:49
  • For people using maven, this looks like this: https://gist.github.com/belkacemlahouel/716f57e6e340ac581a7384e4607fd76e – belka Jan 22 '18 at 14:10
  • 1
    "In java, you can never put an object on stack...affects the performance" This is not true! HotSpot allocates objects on the stack if escape analysis proves that they are not reachable anywhere else. This improves cache locality, but even more so saves on GC costs. This is a major reason for Java's excellent performance. – Aleksandr Dubinsky Mar 23 '20 at 07:16
  • 2
    Is there some way to look at how much stack space your threads are using? Knowing how to change this value is nice, but I'm wondering if there's a JMX metric or something I could look at to tell me what my average and/or maximum thread stack utilization is, so that I can decide when I need to change this value or not. – Dasmowenator Mar 19 '21 at 20:50
15

As you say, local variables and references are stored on the stack. When a method returns, the stack pointer is simply moved back to where it was before the method started, that is, all local data is "removed from the stack". Therefore, there is no garbage collection needed on the stack, that only happens in the heap.

To answer your specific questions:

  • See this question on how to increase the stack size.
  • You can limit the stack growth by:
    • grouping many local variables in an object: that object will be stored in the heap and only the reference is stored on the stack
    • limit the number of nested function calls (typically by not using recursion)
  • For windows, the default stack size is 320k for 32bit and 1024k for 64bit, see this link.
Community
  • 1
  • 1
Vincent van der Weele
  • 12,927
  • 1
  • 33
  • 61
  • eventhough the object which groups local variables is stored in the heap, by the time the method returns, that object is gone. JVM will do some sort of object deferencing. Correct me if I'm wrong – asgs Aug 02 '15 at 15:44
  • 2
    @asgs that's where garbage collection kicks in. If the local variable was indeed the only reference to the object, the object will be removed by GC at some point after the method returns. If the method added some external reference to the object, GC will not remove it. – Vincent van der Weele Aug 02 '15 at 16:43