Memory and Garbage Collector in Java: What Really Happens Under the Hood

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How Java Manages Memory: Not Just "Garbage Collection"

\n\n

Many developers transitioning to Java from C++ or Python initially rejoice: "Great, no need to think about memory leaks!". But then they get an OutOfMemoryError at the most inopportune moment and realize — memory management in Java requires deep understanding. Today we'll look under the hood of the JVM and break down how memory and garbage collector in Java actually work.

\n\n

This article will be useful both for beginners who want to understand the Java memory model, and for experienced developers looking for ways to optimize garbage collection Java. Let's go!

\n\n
\n\n

How Memory is Organized in Java: Heap, Stack, and Metaspace

\n\n

Before talking about the Java garbage collector, you need to understand where exactly your objects "live". The JVM divides memory into several key areas:

\n\n
    \n
  • Heap — stores all created objects. This is the main working area for garbage collection Java.
  • \n
  • Stack — stores primitive types and references to objects in the heap. Each thread has its own stack.
  • \n
  • Metaspace — replaced PermGen in Java 8, stores class metadata.
  • \n
  • Code Cache — code compiled by the JIT compiler.
  • \n
\n\n

Here's a simple example showing where data goes:

\n\n
public class MemoryDemo {\n    public static void main(String[] args) {\n        int number = 42;                    // Primitive — on the stack\n        String text = "Hello";              // Reference on the stack, object in the heap\n        List<String> list = new ArrayList<>(); // Reference on the stack, list in the heap\n        list.add("Java");                   // String "Java" — also in the heap\n    }\n}\n
\n\n

The key point: all objects created via new go into the Java heap. It is this area that the garbage collector in Java "monitors".

\n\n
\n\n

Why the Garbage Collector is Not an Enemy, But a Friend (If You Understand Its Logic)

\n\n

Many developers fear Java GC because of "Stop-The-World" pauses. But let's face the truth: without automatic Java memory management, we would be writing free() manually and catching segfaults. The Java garbage collector is not an evil demon, but a complex, intelligent mechanism.

\n\n

Basic principles of garbage collection Java:

\n\n
    \n
  • An object is considered "garbage" if there are no active references to it from the stack or static fields.
  • \n
  • GC cannot delete an object that still has a reference (even if you forgot about it).
  • \n
  • Different GC algorithms have different goals: minimal pauses, maximum throughput, or memory savings.
  • \n
\n\n

Here's a classic example of a memory leak, when an object is "forgotten" to be removed from a collection:

\n\n
public class LeakExample {\n    private static List<byte[]> cache = new ArrayList<>();\n\n    public static void addToCache() {\n        byte[] data = new byte[1024 * 1024]; // 1 MB\n        cache.add(data); // Reference remains — GC won't touch it\n    }\n\n    public static void main(String[] args) {\n        for (int i = 0; i < 1000; i++) {\n            addToCache();\n        }\n        // Here will be OutOfMemoryError, although the objects are no longer needed\n    }\n}\n
\n\n

Conclusion: memory in Java will not be freed as long as you hold a reference. Understanding this is the first step to writing efficient code.

\n\n
\n\n

Types of Garbage Collectors in Java: From Serial to ZGC

\n\n

Modern Java offers several implementations of garbage collection Java. The choice depends on your tasks:

\n\n

1. Serial GC — for small applications

\n

A single-threaded collector that "freezes" the entire application. Used by

Blogs

Book Recommendations