JVM Garbage Collection: CMS Principles and Tuning
Understanding JVM garbage collection with the CMS collector involves grasping class‑loader hierarchies, memory regions such as Young, Old and Metaspace, the multithreaded ParNew young collector, CMS’s four‑phase mark‑sweep‑compact cycle, and applying tuning parameters—like survivor ratios, tenuring thresholds, and concurrent marking options—to minimize stop‑the‑world pauses and full GCs on typical 4‑core, 8 GB servers.
This article explains the principles and tuning methods of the JVM garbage collector CMS, covering JVM runtime basics, class loading, memory areas, and the ParNew + CMS collectors.
JVM runtime basics
The JVM executes compiled bytecode via class loaders, which follow a hierarchical parent‑delegation model: Bootstrap, Extension, Application, and optional custom loaders. The class loading process includes loading, verification, preparation, resolution, and initialization.
Memory areas
Key areas include the Young generation (Eden and two Survivor spaces), the Old generation, and the Permanent generation (Metaspace). Proper sizing of these areas is crucial to avoid frequent Full GC.
ParNew (young) collector
ParNew is a multithreaded collector for the Young generation, using a copy‑and‑compact algorithm with default Eden:Survivor ratios of 8:1:1. Objects are copied between Survivor spaces, and one Survivor is kept empty.
CMS (old) collector
CMS uses a mark‑sweep‑compact algorithm with four phases: initial mark, concurrent marking, remark, and concurrent sweeping. The initial and remark phases are stop‑the‑world (STW) but short; the other phases run concurrently.
Tuning objectives
The main goal is to reduce STW pause times by minimizing Old‑generation collections and Full GCs. Strategies include:
Preventing objects from being promoted to the Old generation (e.g., adjusting -XX:MaxTenuringThreshold, Survivor sizes, and -XX:PretenureSizeThreshold).
Monitoring GC activity with jstat -gc PID 1000 1000 to track Eden growth, Survivor usage, YGC/YGCT, FGC/FGCT, etc.
Enabling multithreaded initial marking ( -XX:+CMSParallelInitialMarkEnabled) and performing a Young GC before the remark phase ( -XX:+CMSScavengeBeforeRemark).
Setting -XX:+UseCMSCompactAtFullCollection and -XX:CMSFullGCsBeforeCompaction=0 to compact after every Full GC.
Parameter recommendations for a 4‑core, 8 GB machine
Typical JVM options: -Xss1M (thread stack size) -XX:PermSize=256M -XX:MaxPermSize=256M (PermGen/Metaspace) -Xms3072M -Xmx3072M -Xmn2048M (heap, young, old sizes)
-XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:PretenureSizeThreshold=1M -XX:+UseParNewGCand
-XX:+UseConcMarkSweepGC -XX:+CMSParallelInitialMarkEnabled, -XX:+CMSScavengeBeforeRemark, -XX:+UseCMSCompactAtFullCollection, -XX:CMSFullGCsBeforeCompaction=0 By monitoring GC metrics and adjusting these parameters, the JVM can achieve lower pause times, reduced Full GC frequency, and better overall performance.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
