Fundamentals 8 min read

Why Java Objects Aren’t Collected Immediately – A Deep Dive into JVM Memory Allocation

This article explores how JVM memory is allocated, why objects created in methods are not reclaimed instantly, and demonstrates through experiments how Eden space, YGC, and GC behavior affect object lifetimes and overall heap utilization.

Programmer DD
Programmer DD
Programmer DD
Why Java Objects Aren’t Collected Immediately – A Deep Dive into JVM Memory Allocation

Preface

When I first received the request to artificially increase CPU and memory usage on low‑load servers, I was excited because it matched my specialty – writing bugs.

JVM Memory Allocation Review

I quickly wrote a small program to allocate memory and observed its behavior.

java -Djava.rmi.server.hostname=10.xx
-Djava.security.policy=jstatd.all.policy
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=8888
-Xms4g -Xmx4g -jar bug-0.0.1-SNAPSHOT.jar

With these startup parameters I could connect to the application via JMX to monitor memory and GC.

Initially I wondered whether the mem object would be reclaimed immediately after the method finished. Some people assumed it would, but my experiment proved otherwise.

After allocating 250 MB repeatedly, the memory usage curve rose sharply while GC did not trigger, and the object remained in memory.

Using jstat to inspect the heap confirmed that neither Young GC (YGC) nor Full GC (FGC) occurred; only the Eden region usage increased.

Only when the Eden space became almost full (≈98.83 %) did a YGC happen, which finally reclaimed the mem objects and caused the memory curve to drop.

The key takeaway is that an object is reclaimed only when the garbage collector runs, regardless of whether it is a local or global variable. The object must become unreachable, and a GC cycle must occur to collect it.

Objects are first allocated in the young generation’s Eden space, provided they are not too large. Large objects are allocated directly in the old generation.

Prioritize Allocation in Eden

Small objects are placed in Eden, but only if they fit; otherwise they go to the old generation.

Large Objects Directly Enter Old Generation

When I allocated 1000 MB, Eden could not accommodate it, so the allocation went straight to the old generation, increasing its usage by about 37 %.

Linux Memory View

Before starting the application the server used roughly 3 GB of memory. After launching the Java process, memory consumption rose to about 600 MB. To meet the requirement of higher load, I allocated small objects (≈800 MB) to keep the young generation at ~90 % and then allocated large objects to keep the old generation also around 90 %.

By carefully balancing allocations, I avoided triggering any GC cycles, resulting in a total memory consumption of about 3.5 GB without additional GC pauses.

Summary

Controlling JVM memory allocation precisely is not trivial; it requires a solid understanding of heap layout, GC triggers, and the distinction between reachable and unreachable objects.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceMemory ManagementGarbage CollectionEden Space
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.