Memory Management in Java: Stack vs. Heap & Garbage Collection

Abhishek Kumar - Oct 2 - - Dev Community

Java handles memory management through two key areas: the stack and the heap. Understanding the differences between these two memory areas and how Java manages them via garbage collection is essential for writing efficient applications.


1. Stack Memory

The stack is a region of memory that stores local variables and method call information. It follows the Last In, First Out (LIFO) principle, where memory is allocated and freed in the reverse order in which it was used.

Key Features of Stack:

  • Used for:
    • Primitive data types (int, char, boolean, etc.)
    • References to objects (but not the objects themselves)
    • Method call frames (including method parameters and local variables)
  • Memory Size: Typically smaller and more limited than heap memory.
  • Memory Allocation: Happens automatically as methods are called.
  • Memory Deallocation: Happens when methods return, and the variables in those methods are automatically removed from the stack.
  • Speed: Very fast compared to heap memory because access is predictable (LIFO).
  • Scope: Variables stored in the stack are limited to the current method. Once the method finishes, the memory is cleared.
  • Thread-Specific: Each thread has its own stack memory.

Example of Stack Usage:

public class StackExample {
    public static void main(String[] args) {
        int x = 10;  // Stored in the stack
        int y = 20;  // Stored in the stack
        int result = add(x, y);  // Method call adds a new stack frame
    }

    public static int add(int a, int b) {
        int sum = a + b;  // a, b, and sum are stored in the stack
        return sum;  // When the method finishes, the frame is removed
    }
}
Enter fullscreen mode Exit fullscreen mode
  • x, y, a, b, and sum are all stored in the stack.
  • Each method call creates a new frame in the stack, and when the method returns, the frame is cleared.

2. Heap Memory

The heap is a region of memory used to store objects and dynamic memory. It is larger and more flexible than the stack, but access to heap memory is slower because it doesn't follow the strict LIFO order.

Key Features of Heap:

  • Used for:
    • Objects created using new (e.g., new Integer(5))
    • Instance variables of objects
  • Memory Size: Generally larger than the stack.
  • Memory Allocation: Objects are dynamically allocated at runtime.
  • Memory Deallocation: Managed by Java's Garbage Collector (more on this later), which automatically frees up memory that is no longer in use.
  • Speed: Slower than stack memory, as objects are scattered in memory, and access requires pointer dereferencing.
  • Scope: Objects in the heap persist as long as they are referenced by any part of the program. They are only deallocated when they are no longer referenced.

Example of Heap Usage:

public class HeapExample {
    public static void main(String[] args) {
        Person person1 = new Person("John");  // Stored in the heap
        Person person2 = new Person("Alice");  // Stored in the heap
    }
}

class Person {
    String name;
    Person(String name) {
        this.name = name;  // The String object is also in the heap
    }
}
Enter fullscreen mode Exit fullscreen mode
  • The Person objects and their name fields are stored in the heap.
  • Variables like person1 and person2 are stored in the stack but hold references (pointers) to the objects in the heap.

3. Stack vs. Heap: Key Differences

Stack Heap
Stores local variables and method call frames Stores objects and instance variables
Memory deallocation happens automatically when a method completes Memory deallocation is handled by Garbage Collection
LIFO (Last In, First Out) memory management Objects are randomly allocated and may be scattered
Smaller size, typically limited Larger size, shared by the entire application
Faster access, due to its structure Slower access, due to dynamic allocation
Thread-specific: Each thread has its own stack Global: All threads share the heap memory

4. Garbage Collection

Java provides automatic memory management via Garbage Collection (GC). The garbage collector automatically reclaims memory that is no longer reachable by the program, freeing developers from manual memory management (as in languages like C or C++).

How Garbage Collection Works:

  • Objects in the heap that are no longer referenced by any part of the program are considered garbage.
  • GC Roots: The garbage collector starts from "roots," which are references from active stack frames, static variables, or thread references, and tracks all objects that are still reachable.
  • Unreachable objects: Any object that cannot be reached from GC roots is considered eligible for garbage collection.
  • Deallocation: The garbage collector automatically deallocates the memory used by unreachable objects, freeing up heap space.

Phases of Garbage Collection:

  1. Marking: The GC identifies all live (reachable) objects.
  2. Deletion (Sweeping): It removes objects that are no longer reachable.
  3. Compacting (optional): In some garbage collectors, the heap is compacted to eliminate fragmentation, making memory allocation more efficient.

Example of Garbage Collection:

public class GarbageCollectionExample {
    public static void main(String[] args) {
        Person person1 = new Person("John");
        person1 = null;  // Now, the "John" object is eligible for garbage collection

        Person person2 = new Person("Alice");
        // "Alice" is still referenced, so it's not eligible for garbage collection
    }
}
Enter fullscreen mode Exit fullscreen mode
  • The Person object holding "John" is no longer referenced, so it becomes eligible for garbage collection.
  • The garbage collector will eventually reclaim the memory used by "John", but "Alice" is still in use.

Garbage Collection Types

There are different algorithms and approaches for garbage collection:

  • Serial Garbage Collector: Single-threaded garbage collection; ideal for small applications.
  • Parallel Garbage Collector: Uses multiple threads for garbage collection.
  • CMS (Concurrent Mark-Sweep) Garbage Collector: Minimizes stop-the-world events by running alongside the application.
  • G1 Garbage Collector: Divides the heap into regions and uses both parallel and concurrent approaches for efficiency.

Important Points to Remember:

  • The stack is used for method calls and local variables, while the heap is used for objects.
  • Stack memory is faster but limited, while heap memory is larger but slower.
  • Java’s Garbage Collector automatically manages heap memory, reclaiming space from objects that are no longer in use.

This memory management system allows Java developers to focus more on building applications without worrying about manual memory allocation and deallocation.

. . . . . . . . . . . .
Terabox Video Player