[!NOTE] In legacy C/C++, if you allocated memory for 10,000
Carobjects, it was your explicit responsibility to order the CPU tofree()that memory when you finished. If you forgot, the RAM filled up endlessly until the computer suffered a Blue Screen of Death. This is called a "Memory Leak".
Java completely automated this with the Garbage Collector (GC), heavily influencing the design of C# and Go.
The Heap Memory
Every time you execute the new keyword (e.g., new Car()), Java allocates physical space in an area of RAM called the Heap.
public void processOrders() {
// 1. Spawns an object on the massive Heap.
// The 'report' variable on the Stack is just a pointer pointing to the Heap object!
OrderReport report = new OrderReport();
report.compile();
} // 2. Method ends. The 'report' pointer is destroyed.
When the method finishes, the report pointer is destroyed. But the massive OrderReport object is still sitting entirely intact out on the Heap, consuming megabytes of RAM!
The Tracing Garbage Collector
Because no active variables are currently pointing to that OrderReport object, it is officially orphaned. It is impossible for your code to ever access it again.
A daemon thread called the Garbage Collector sleeps in the background. Periodically, it wakes up and pauses the application.
- Mark Phase: It traces every single active variable in your program, painting the objects they point to as "Alive".
- Sweep Phase: It scans the entire Heap array. Any orphaned object that the Mark phase didn't paint is annihilated. The RAM is recovered!
The Risk of Memory Leaks in Java
Wait, if Java automatically sweeps orphaned objects, how can a Java Server suffer a Memory Leak?
If you maintain a massive static (global) ArrayList, and endlessly add items to it, they are technically never orphaned.
public class Cache {
// A single global list
public static ArrayList<User> staticUserCache = new ArrayList<>();
public void loginUser() {
// We endlessly add users, but NEVER call .remove()
staticUserCache.add(new User());
}
}
Because the staticUserCache variable is permanently alive (it's attached to the Class itself), the millions of User objects inside it are never considered "orphaned". The Garbage Collector refuses to touch them. Eventually, your JVM crashes with a catastrophic OutOfMemoryError.