What is the default stack size, can it grow, how does it work with garbage collection?
Categories:
Understanding Java Stack Size, Growth, and Garbage Collection

Explore the default stack size in Java, how it can be configured, its dynamic growth capabilities, and its relationship with garbage collection.
In Java, understanding memory management is crucial for writing efficient and stable applications. The stack is a fundamental memory area that plays a significant role in method execution and local variable storage. This article delves into the default stack size, how it can be adjusted, its dynamic behavior, and its interaction with Java's automatic garbage collection process.
What is the Java Stack and its Default Size?
The Java Virtual Machine (JVM) allocates a separate stack for each thread. This stack is primarily used for storing local variables, method parameters, and return addresses during method invocations. Unlike the heap, which stores objects, the stack operates on a Last-In, First-Out (LIFO) principle, where method calls are pushed onto the stack and popped off upon completion.
The default stack size is not fixed across all JVM implementations and operating systems. It typically ranges from 256KB to 1MB for 64-bit systems. For instance, on many Linux systems, the default might be 1MB, while on some Windows systems, it could be 256KB or 512KB. This default is often sufficient for most applications, but complex recursive algorithms or applications with deep call stacks might require adjustments.
StackOverflowError
occurs, then analyzing the stack trace depth. Alternatively, use JVM options like -XX:+PrintFlagsFinal
and search for ThreadStackSize
.Configuring Stack Size and Dynamic Growth
Java provides command-line options to explicitly set the stack size for threads. The primary option is -Xss
. This allows you to specify the stack size in bytes, kilobytes (k/K), or megabytes (m/M).
For example, to set the stack size to 2 megabytes:
java -Xss2m YourApplication
It's important to note that while you can set an initial stack size, the Java stack does not dynamically grow in the same way the heap does. Once a thread's stack is allocated with a certain size, it remains that size. If a thread attempts to push more frames onto its stack than the allocated size allows, a StackOverflowError
will be thrown. This is a critical distinction from the heap, which can expand or shrink based on memory pressure and garbage collection cycles.
Therefore, when you set -Xss
, you are defining the maximum size that thread's stack can reach. There is no automatic resizing mechanism for individual thread stacks during runtime.
public class StackSizeExample {
private static int counter = 0;
public static void recursiveMethod() {
System.out.println("Call depth: " + counter++);
recursiveMethod(); // Infinite recursion
}
public static void main(String[] args) {
try {
recursiveMethod();
} catch (StackOverflowError e) {
System.err.println("StackOverflowError caught at depth: " + counter);
// e.printStackTrace(); // Uncomment to see full stack trace
}
}
}
flowchart TD A[JVM Starts] --> B{New Thread Created?} B -- Yes --> C[Allocate Thread Stack] C -- Size from -Xss or Default --> D[Execute Method] D -- Push Frame --> E{Stack Full?} E -- No --> D E -- Yes --> F[StackOverflowError] B -- No --> G[Application Continues] F --> H[Application Crash/Error Handling]
Flowchart illustrating thread stack allocation and StackOverflowError
Stack vs. Heap: Interaction with Garbage Collection
The stack and the heap are distinct memory regions with different management mechanisms and relationships with garbage collection (GC).
Stack Memory: This memory is managed automatically by the JVM on a per-thread basis. When a method is called, a new stack frame is pushed onto the stack. When the method completes, its stack frame is popped off. Local variables and method parameters stored on the stack are automatically deallocated when their scope ends. Garbage collection does not operate on stack memory. Its lifecycle is tied directly to method invocation and completion.
Heap Memory: This is where all Java objects (instances of classes) are stored. Heap memory is shared among all threads in the application. Unlike stack memory, objects on the heap are not automatically deallocated when their creating method finishes. Instead, they remain in memory until they are no longer reachable by any active part of the program. This is where Garbage Collection (GC) comes into play. The GC identifies and reclaims memory occupied by unreachable objects, making it available for new object allocations.
While GC doesn't directly manage stack memory, there's an indirect relationship: the references to heap objects stored as local variables on the stack are crucial for GC to determine object reachability. If the only reference to a heap object exists within a stack frame, and that frame is popped, the object may become eligible for garbage collection.
sequenceDiagram participant Thread participant Stack participant Heap participant GC as Garbage Collector Thread->>Stack: Call methodA() Stack->>Stack: Push frame for methodA() methodA()->>Heap: Create Object A Stack->>Stack: Store reference to Object A Thread->>Stack: Call methodB() Stack->>Stack: Push frame for methodB() methodB()->>Heap: Create Object B Stack->>Stack: Store reference to Object B Thread->>Stack: Return from methodB() Stack->>Stack: Pop frame for methodB() Note over Stack,Heap: Object B becomes unreachable if no other references exist GC->>Heap: Identify unreachable objects (e.g., Object B) GC->>Heap: Reclaim memory of Object B Thread->>Stack: Return from methodA() Stack->>Stack: Pop frame for methodA() Note over Stack,Heap: Object A becomes unreachable if no other references exist GC->>Heap: Identify unreachable objects (e.g., Object A) GC->>Heap: Reclaim memory of Object A
Sequence diagram illustrating stack and heap interaction with garbage collection
StackOverflowError
s, especially with deep recursion. Setting it too large can waste memory, as each thread will reserve that amount, potentially leading to OutOfMemoryError
if too many threads are created.