Java Memory Model
Memory Leaks
Identify how memory leaks occur in Java, analyze heap profiles, and prevent resource leaks.
Interview: Commonly tested by presenting a leaky class (e.g. custom stack using array without nulling out references) and asking you to fix it.
A memory leak in Java occurs when heap objects are no longer needed by the program, but remain reachable from GC Roots. Because they are reachable, the GC cannot reclaim them, leading to an eventual OutOfMemoryError.
Core Idea
Memory leaks are caused by holding onto object references long after their useful lifetime.
Why It Matters
Leaky code slowly degrades container resource limits, causing container crash-loops in Kubernetes.
Interview Lens
Expect design reviews: inspect code containing static collections, listeners, or missing cleanup blocks.
Common Memory Leak Sources
- Static Collections: Static fields persist for the lifetime of the application. Placing objects into a static collection (like HashMap) without cleanup leaks them.
- Unclosed Resources: Forgetting to close database connections, sockets, or file streams leaks OS descriptors and memory.
- Unregistered Listeners: Registering callbacks or event listeners without removing them preserves the subscriber instance reference.
- Array Slices / Custom Buffers: Failing to null out array elements in custom stacks or lists when popping items.
Code Walkthrough
The following class simulates a leak using custom arrays and demonstrates the fix.
public class LeakyStack { private Object[] elements = new Object[100]; private int size = 0;public void push(Object o) { elements[size++] = o; }
public Object pop() { if (size == 0) throw new IllegalStateException(); // Return object but keep reference in array -> LEAK! // return elements[--size];
// FIX: Reclaim index allocation Object result = elements[--size]; elements[size] = null; // Dereference pointer return result; } }
Interview-Relevant Information
Q: How do you diagnose a memory leak in production?
Answer: You can capture a heap dump using jmap -dump:format=b,file=heap.hprof or tool profiling flags. Analyzing the dump inside tools like Eclipse Memory Analyzer (MAT) allows searching for the object type consuming the most memory and tracing its incoming reference tree back to the GC Root.
Quick Checklist
Why do static variables cause leaks? Why should you null out indices in custom queues? If yes, you understand memory leaks.
Use Cases
Writing safe, leak-free custom data containers (stacks, ring buffers).
Profiling application heap allocations to identify memory footprints.
Common Mistakes
Not closing resources via try-with-resources, leaving raw stream buffers open in memory.
Failing to override equals() and hashCode() on custom keys, causing duplicate key insertions in maps.