Java.Core.Fragmentation and Regions

🌐 What is Fragmentation in Java?

What causes fragmentation?

  • When objects are allocated and then freed, they leave gaps in memory.
  • These gaps are too small for new objects to fit, even though there’s technically free space available.
  • Over time, memory becomes fragmented — lots of small unused spaces scattered across the heap, making it inefficient for larger objects to be allocated.

Example

Imagine this memory block:

| Block 1 (live) | Block 2 (free) | Block 3 (live) | Block 4 (free) | Block 5 (live) |

Now if you want to allocate a large object, there’s no single continuous space big enough. This is external fragmentation.


🔨 How older GCs handled fragmentation (pre-Java 8)

1. Compaction (Stop-the-World)

  • After removing garbage, some collectors (like Serial GC) would compact the heap by moving all live objects next to each other.
  • This eliminated gaps but required a stop-the-world pause — freezing the application until compaction completed.
  • This worked, but wasn’t scalable for large heaps.

2. CMS GC (deprecated) — No Compaction

  • CMS tried to avoid full compaction to reduce pause times.
  • This led to fragmentation issues over time, especially in long-running applications.
  • When fragmentation got severe, a full GC (with compaction) was forced — a big pause hit.

🚀 How Modern GCs (G1, ZGC, Shenandoah) Solve Fragmentation

1. Region-based Memory Management (G1 GC)

  • Instead of a single continuous heap, G1 splits the heap into fixed-size regions.
  • Each region can hold either young objects or old objects, but regions are independent.
  • When a region becomes mostly garbage, the GC reclaims and compacts only that region — a small, quick operation.

✅ This local compaction avoids the need for a huge global compaction pause.


2. Relocation and Concurrent Compaction (ZGC & Shenandoah)

  • These modern collectors support concurrent compaction, meaning:
    • Live objects are moved while the application is still running.
    • This avoids stop-the-world pauses, even for very large heaps (100+ GB).
  • They also rely on regions and relocation tables to track object moves efficiently.

✅ This makes fragmentation almost a non-issue in ZGC and Shenandoah, even in massive heaps.


Summary Table

CollectorFragmentation Handling
Serial GCFull compaction (stop-the-world)
Parallel GCFull compaction (stop-the-world)
CMS GCMinimal compaction (causes fragmentation over time)
G1 GCRegional compaction (low pause, fragmentation-resistant)
ZGC & ShenandoahConcurrent, regional compaction (almost no pause, scales to huge heaps)

📊 Key Takeaways

✅ Older GCs (Serial, Parallel, CMS) struggled with fragmentation in large or long-running apps.
✅ Modern GCs (G1, ZGC, Shenandoah) minimize fragmentation using region-based memory and incremental or concurrent compaction.
✅ As of Java 17+, G1 is the default, making fragmentation a much smaller concern for most applications.

This entry was posted in Без рубрики. Bookmark the permalink.