CMS (Concurrent Mark Sweep) Garbage Collector Explained

Illustration for CMS (Concurrent Mark Sweep) Garbage Collector Explained
By Last updated:

Before G1, ZGC, and Shenandoah, the Concurrent Mark-Sweep (CMS) Garbage Collector was the go-to option for developers needing low-latency garbage collection in Java. CMS minimized Stop-the-World (STW) pauses by performing most of its work concurrently with the application threads.

In this tutorial, we’ll explore the CMS Garbage Collector in detail, including how it works, its phases, tuning options, strengths, limitations, and why it was eventually deprecated.


Why CMS Matters in JVM History

  • First widely used low-latency GC in Java.
  • Minimized pauses compared to Serial and Parallel GC.
  • Popular in financial trading systems, telecom apps, and web servers where latency was critical.
  • Served as the foundation for G1, ZGC, and Shenandoah.

Analogy: CMS is like cleaning your house while people are still inside. It’s faster than stopping everything, but you may miss a few spots or need retries.


How CMS Works: The GC Phases

CMS is based on the Mark-and-Sweep algorithm but adds concurrency.

Phases of CMS

  1. Initial Mark (STW)

    • Stops the world briefly.
    • Marks objects directly reachable from GC roots.
  2. Concurrent Mark

    • Runs with application threads.
    • Traces the object graph from the roots.
  3. Remark (STW)

    • Stops the world again.
    • Catches objects that were missed due to concurrent modifications.
  4. Concurrent Sweep

    • Reclaims unreferenced objects while application threads continue.
[Initial Mark - STW] → [Concurrent Mark] → [Remark - STW] → [Concurrent Sweep]

Example: Enabling CMS in Java

java -XX:+UseConcMarkSweepGC -Xms512m -Xmx512m MyApplication
  • -XX:+UseConcMarkSweepGC enables CMS.
  • Often combined with -XX:+UseParNewGC for parallel young generation GC.

Strengths of CMS

  • Low pause times due to concurrent phases.
  • Improved responsiveness for interactive applications.
  • Suitable for applications with large heaps and short response time requirements.

Limitations of CMS

  • Fragmentation → Unlike compacting collectors, CMS leaves free memory scattered.
  • Floating Garbage → Objects created during concurrent phases may be missed until the next cycle.
  • CPU Intensive → Requires extra CPU since GC threads run alongside application threads.
  • Complex tuning → Needed flags like -XX:CMSInitiatingOccupancyFraction.
  • Deprecated in Java 9 and removed in Java 14.

CMS vs G1 GC

Feature CMS G1 GC
Compaction No (causes fragmentation) Yes (region-based compaction)
Pause Times Short (low latency) Predictable (configurable goals)
Default Status Deprecated, removed in J14 Default from Java 9 onwards
Heap Management Old Gen only Region-based (Young + Old)

Real-World Case Study

A stock trading platform used CMS to keep GC pauses under 50ms. Over time, heap fragmentation caused OutOfMemoryErrors. Migrating to G1 GC improved stability, since G1 handled compaction and balanced throughput with latency.


JVM Version Tracker

  • Java 8 → CMS widely used for low-latency systems.
  • Java 9 → CMS deprecated, G1 became default.
  • Java 14 → CMS removed completely.
  • Java 17+ → ZGC and Shenandoah introduced as stable low-latency options.

Best Practices When Using CMS (Legacy Systems)

  • Tune with:

    • -XX:+UseParNewGC → Parallel young gen collection.
    • -XX:CMSInitiatingOccupancyFraction=70 → Start CMS when old gen is 70% full.
    • -XX:+UseCMSCompactAtFullCollection → Occasionally compact heap.
  • Monitor with GC logs:

    -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log
    
  • Migrate to G1 GC or ZGC/Shenandoah in modern JVMs.


Conclusion & Key Takeaways

  • CMS was a revolutionary GC that reduced pause times with concurrent collection.
  • Its biggest flaws: fragmentation and complexity.
  • Deprecated in Java 9 and removed in Java 14.
  • For modern apps, use G1, ZGC, or Shenandoah instead.
  • Understanding CMS is important for JVM history and legacy system maintenance.

FAQs

1. What is the JVM memory model and why does it matter?
It defines how threads interact with memory, ensuring correctness and safety.

2. How does G1 GC differ from CMS?
G1 avoids fragmentation with region compaction, while CMS suffered from scattered free memory.

3. Why was CMS deprecated?
High fragmentation, tuning complexity, and better alternatives (G1).

4. What is floating garbage in CMS?
Garbage created during concurrent phases, collected only in later cycles.

5. How do I tune CMS for better performance?
Adjust CMSInitiatingOccupancyFraction, enable compaction, and monitor GC logs.

6. What replaced CMS?
G1 GC is the default, while ZGC and Shenandoah provide low-latency options.

7. What’s the main downside of CMS?
Fragmentation and occasional long pauses due to remark and compaction.

8. How do GC logs show CMS activity?
Logs display initial mark, remark, and concurrent phases.

9. Can CMS still be used today?
Only in legacy Java 8 systems; not available in Java 14+.

10. What’s new in Java 21 for GC?
NUMA-aware GC and Project Lilliput improve performance, with ZGC and Shenandoah as modern low-latency collectors.