Memory management in Java

Java manages memory automatically using a Garbage Collector (GC), which frees developers from explicitly allocating and deallocating memory like in C or C++. Let’s break it down clearly with an example.


🔹 Memory Management in Java

Java memory is mainly divided into two parts:

1. Heap Area

  • Where all objects are stored.
  • Divided into:
    • Young Generation – for new objects.
    • Old Generation – for long-lived objects.
  • Garbage Collector (GC) cleans up unused objects here.

2. Stack Area

  • Each thread has its own stack.
  • Stores:
    • Local variables
    • Method calls
    • Object references (pointers to heap objects)
  • Automatically cleared when a method ends.

3. Method Area (or MetaSpace)

  • Stores:
    • Class info (methods, variables, constants)
    • Static variables
  • Shared among all threads.

4. Other Small Areas

  • PC Register: keeps track of the current instruction.
  • Native Method Stack: used for native (C/C++) code.

    🔄 How Garbage Collection Works

    • An object becomes eligible for GC when no live thread can access it (no references point to it).
    • GC automatically reclaims that memory.

    ✅ Example: Memory Management in Java

    public class MemoryManagementExample {
    
        static class Student {
            String name;
    
            Student(String name) {
                this.name = name;
            }
    
            @Override
            protected void finalize() throws Throwable {
                System.out.println("Garbage Collected: " + name);
            }
        }
    
        public static void main(String[] args) {
            // Stack stores references, Heap stores objects
            Student s1 = new Student("Alice");
            Student s2 = new Student("Bob");
    
            // Now s1 points to a new object
            s1 = new Student("Charlie");
    
            // "Alice" object is no longer referenced -> eligible for GC
            // Forcing garbage collection (not guaranteed)
            System.gc();
    
            System.out.println("Program finished.");
        }
    }
    

    🔎 Explanation

    1. s1 = new Student("Alice");Alice object created in heap, s1 reference on stack.
    2. s2 = new Student("Bob");Bob object created in heap.
    3. s1 = new Student("Charlie"); → old reference to Alice is lost, so "Alice" becomes eligible for GC.
    4. System.gc(); requests GC to run (not guaranteed immediately).
    5. The finalize() method prints when GC collects the object.

    🧠 Key Points

    • Developers don’t manually free memory in Java.
    • GC handles unused objects automatically.
    • Avoid memory leaks by removing unnecessary references (e.g., nulling out large collections when done).

    Leave a Reply