Parallel与CMS垃圾收集的区别及CMS各阶段含义咨询
Hey Neha, totally get where you're coming from—GC can feel like a confusing maze when you're just starting out, especially when you run into conflicting info like:
"Parallel使用多个GC线程,而CMS仅使用一个"
"CMS uses multiple threads (“concurrent”) to scan through the heap (“mark”) for unused objects that can be recycled (“sweep”)"
Let's clear up that confusion first, then break down the key differences between the two collectors, and finally walk through CMS's phases in plain language.
First off: the claim that CMS uses only one thread is wrong. Both collectors use multiple threads for garbage collection work—their differences lie in when and how those threads run, and what they prioritize.
Core Priorities
- Parallel Collector: Focuses on throughput—it wants your application to spend as much time doing its actual work as possible. It does this by running full garbage collection in short, infrequent (but sometimes longer) stop-the-world (STW) pauses, using multiple threads to finish the cleanup fast.
- CMS Collector: Focuses on low latency—it aims to keep STW pauses as short as possible, even if that means using more CPU resources in the background while your app runs. Most of its work happens concurrently with your application.
How They Work
- Parallel:
- Uses a mark-sweep-compact algorithm for the old generation. When it runs, it pauses your entire app, marks all live objects, sweeps away the unused ones, then compacts the remaining objects to free up contiguous heap space.
- Great for batch applications, backend services, or any scenario where occasional longer pauses are acceptable in exchange for higher overall throughput.
- CMS:
- Uses a mark-sweep algorithm (no default compaction) for the old generation. Most of the marking and sweeping happens in the background, alongside your app. Only two short STW pauses occur during its cycle.
- Ideal for interactive applications, GUIs, or services where consistent low latency is critical (like e-commerce platforms or real-time tools).
Pause Behavior
- Parallel: Longer STW pauses (milliseconds to even seconds, depending on heap size), but these happen less often if your app's garbage generation is steady.
- CMS: Very short STW pauses (usually just a few milliseconds), but it may have more frequent minor collections, and can fall back to a full STW collection if it can't keep up with garbage production (or if heap fragmentation becomes too bad).
Let's break down each phase of the CMS cycle in simple terms:
initial mark(STW Pause)- This is the first, super-short pause. CMS only marks the root objects—things like references from the application stack, static variables, and JVM-internal references. It doesn't traverse the entire heap here, so it's over in a blink.
concurrent mark- Your application resumes running! CMS spins up background threads to traverse the heap starting from the marked roots, marking all objects that are still in use. Since this runs alongside your app, there's no pause—but any new objects created or references changed during this phase aren't tracked yet.
remark(STW Pause)- Another short pause (usually a bit longer than initial mark). CMS fixes the gaps from the concurrent mark phase: it re-scans the roots and uses a "card table" (a tracking mechanism) to find any objects that were modified while the concurrent mark was running. This ensures every live object is correctly marked before sweeping.
sweeping phase(Concurrent Sweep)- Your app keeps running. CMS's background threads go through the heap and clean up all unmarked (unused) objects, freeing up space. Unlike Parallel, CMS doesn't compact the heap here—so over time, the heap can become fragmented, which might eventually trigger a full compacting collection.
- (Optional) Concurrent Reset
- A final background phase where CMS resets its internal data structures to get ready for the next collection cycle. This has no impact on your application.
内容的提问来源于stack exchange,提问作者Neha

