Java Tutorial
Java Garbage Collection
Java frees objects you can no longer reach. You do not call delete — drop the last reference and the GC can reclaim the memory.
No delete
C++ has new and delete. Java has new and a garbage collector. When no live variable can reach an object, the collector may free it. You do not pick the exact moment — and you usually should not try.
Example
public class Main {
public static void main(String[] args) {
String a = "keep";
String b = a;
a = null;
System.out.println(b); // still "keep" — b holds a reference
}
}Reachability
An object stays alive while any reference chain from a live root (local variables, static fields, …) can reach it. Set every reference to null or let them go out of scope, and the object becomes garbage. Java has no dangling pointers — only null.
Example
public class Main {
public static void main(String[] args) {
int[] data = new int[1_000_000];
data[0] = 42;
System.out.println(data[0]);
data = null; // large array becomes unreachable (GC may reclaim later)
}
}Objects replace objects
Reassigning a variable drops the old reference. If nothing else pointed at the previous object, it is eligible for collection. This is normal — short-lived objects are cheap in modern JVMs.
Example
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("hi");
sb = new StringBuilder("bye"); // first builder may become garbage
System.out.println(sb);
}
}You almost never call System.gc(). It is only a hint, and forcing collection rarely helps application code. Write clear ownership; let the collector do its job.
What you still manage
The GC frees memory, not every resource. Close files, sockets, and database connections yourself — preferably with try-with-resources.
Example
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try (Scanner sc = new Scanner("3 4")) {
System.out.println(sc.nextInt() + sc.nextInt());
} // Scanner closed here even if an error occurs
}
}Holding large collections in static fields keeps them reachable for the whole process. Clear or shrink caches you no longer need, or they will never become garbage.
Try It Yourself
Exercise: Create two variables that refer to the same int[]. Null one out, then print an element through the other. Which reference keeps the array alive?
Show solution
int[] a = {1, 2, 3};
int[] b = a;
a = null;
System.out.println(b[1]); // 2 — b still reaches the arrayb keeps the array reachable. Only when the last reference is gone can the GC reclaim it.
Key Takeaways
- Java has no
delete— unreachable objects are eligible for garbage collection. - Reachability, not “I finished using it in my head,” decides when memory can be freed.
- Close external resources yourself; GC does not replace try-with-resources.
- Avoid long-lived static references to huge data you no longer need.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the Java editor at /java/try. Change one measurement and check whether the result still has the right unit.
Engineering
Drop a buffer reference
When no live variable points at an object, the garbage collector may reclaim it. Setting the only reference to null is how you say you are done.
Example
public class Main {
public static void main(String[] args) {
String buf = "sensor-batch-1";
System.out.println(buf);
buf = null;
System.out.println(buf == null);
}
}