๐พ Understanding Java Memory & Garbage Collection
In modern Java applications, memory management is crucial for performance, stability, and avoiding crashes. This post dives into Heap, Stack, Garbage Collection, and memory leaks, with practical examples and tips for Java 8+ and latest versions. ๐
1. ๐ง Heap vs Stack
- Heap: Dynamic memory allocation for objects. Managed at the application level.
- ๐ฑ Young Generation: Newly created objects; includes Eden + Survivor spaces.
- ๐ฐ Old Generation: Objects that survive threshold; long-lived objects.
- ๐ Metaspace (PermGen replaced in Java 8+): JVM metadata, classes, and method info.
- Stack: Static memory for method calls, local variables, and primitive values. Automatically deallocated when methods complete.
2. ๐ Java Object References & String Pool
Objects in Java are stored in the heap, and the String pool helps reuse memory for string literals:
String x1 = "Java";
String x2 = "Java1";
String x3 = "Java";
String x4 = new String("Java");
// x1 == x3 → true (String pool reuses object)
// x1 == x4 → false (new object on heap)
3. ♻️ Garbage Collection (GC)
GC automatically identifies and removes unreachable objects to free heap memory.
- Minor / Incremental GC: cleans unused objects in young generation.
- Major / Full GC: cleans objects not removed earlier, including old generation.
- Make objects eligible for GC:
- Nullifying reference variables
- Reassigning references
- Objects created inside methods (local scope)
- Island of Isolation
- Requesting GC:
System.gc()
orRuntime.getRuntime().gc()
(no guarantees).
4. ⚠️ Common Memory Errors
- StackOverflowError: Non-thread-safe; occurs when call stack overflows (recursive calls).
- OutOfMemoryError: Heap exhausted; GC could not reclaim enough memory.
5. ๐ Memory Leaks
Memory leaks occur when objects remain referenced and cannot be GC’ed. Causes include:
- Static references holding large objects
- Unclosed streams, files, sockets, connections
- Improperly implemented
hashCode()
&equals()
in collections - Native resources not freed
Detection tools:
- ๐ป VisualVM
- ๐ JProfiler
- ๐ Java Flight Recorder (JFR)
6. ๐ Modern Java GC & Memory Features
- G1 GC: Default for Java 9+, low pause time for large heaps.
- ZGC & Shenandoah: Ultra-low pause, scalable for huge heaps (Java 11+).
- Compressed OOPs: Save memory for 64-bit JVMs.
- Compact Strings (Java 9+): Use byte arrays instead of char[] for Latin-1.
7. ๐ Example: Making Objects Eligible for GC
public void example() {
String s = new String("Hello"); // object created on heap
s = null; // eligible for GC
// object will be removed in next GC cycle
}
8. ๐ Summary Table
Memory Area | Purpose | Notes |
---|---|---|
Heap | Dynamic memory for objects | Young, Old, Metaspace; GC cleans unreachable objects |
Stack | Local variables, primitive values | Automatic deallocation; StackOverflowError on overflow |
String Pool | Reuses string literals | Reduces heap usage; beware of new String() vs literal |
9. ๐ผ Memory Diagram
Young Gen
Short-lived objects
Old Gen
Long-lived objects
Metaspace
Class metadata
Stack
Method calls & local variables
10. ๐ Tips for Modern Java Applications
- Prefer local variables and scopes to help GC.
- Always close streams, connections, and resources (try-with-resources).
- Monitor heap usage with VisualVM or Flight Recorder in production.
- Tune GC for large applications (G1, ZGC, or Shenandoah).
- Use immutable objects carefully to reduce memory churn.
- Consider object pooling only for very heavy objects; avoid premature optimization.
Labels: Java, Memory, Garbage Collection, Heap, Stack, GC, Modern Java, Performance, Java 8+, Java 11+
Comments
Post a Comment