Memory Management and Garbage Collection
Who Cleans Up the Memory?
In Java you never free memory yourself. Objects live on the heap; a background process called the garbage collector (GC) finds objects that the program can no longer reach and reclaims their space.
How Garbage Collection Works
- Objects are reachable if a stack reference points to them, directly or indirectly.
- When an object becomes unreachable, it is eligible for collection.
- Threshold triggers: the collector may also visit threads and other GC roots.
The common modern collectors use a generational design: young objects are allocated in a fast nursery, and objects that survive several collections are promoted to an older generation that is scanned less often.
Forcing an Object to Be Eligible
class Sample {
String label;
Sample(String label) { this.label = label; }
}
Sample a = new Sample("first");
Sample b = new Sample("second");
a = b; // 'first' object becomes unreachable
b = null; // 'second' object becomes unreachable tooYou Can Suggest, Not Command
System.gc(); // a suggestion; the JVM is free to ignore itCalling System.gc() in normal code is rarely a good idea - trust the collector's tuning.
What the JVM Tracks
- Heap: holds all objects and arrays.
- Thread stacks: hold method call frames and local variables.
- Metaspace: holds class metadata.
You can watch memory live with:
java -Xmx512m -Xlog:gc MyProgramHere -Xmx512m caps the heap at 512 MB and GC logging prints collection activity.
The finalize Caveat
The old finalize() hook has been deprecated (removed in Java 18 territory). Cleanup should be done deliberately - via try-with-resources or an explicit close() - never by hoping the collector calls a finalizer.







- The GC reclaims unreachable objects automatically - no free() needed.
- Modern JVMs use generational collectors tuned by default.
- Never rely on System.gc() or finalizers for correctness.