Mastering Java JVM Tuning: Essential Commands, GC Strategies, and Reference Types
This guide explains how to launch Java processes from the command line, details key JVM tuning flags such as -X and -XX options, describes garbage collection algorithms, reference strengths, and stop‑the‑world pauses, providing practical examples and diagrams to help developers optimize memory usage and performance.
1. Java Process Command Line Startup
<code>java [-options] main_class_name [args...]</code>2. Java Tuning Parameters
The JVM’s non‑standard
-Xoptions vary across versions; you can list them with
java -X. The
-XXoptions are also non‑standard and are mainly used for tuning and debugging; view all of them with
java -XX:+PrintFlagsFinal -version. There are two ways to use
-XXflags:
Boolean type : format
-XX:+ | -XX:-Non‑boolean type : format
-XX:NewRatio=2 <code>-Xmx30M // specify maximum heap memory
-Xms30M // specify minimum heap memory
-Xss128K // specify maximum thread stack memory
-Xmn20M // specify young generation size (usually 1/3 or 1/4 of heap)
-XX:MaxDirectMemorySize // set maximum direct memory size (off‑heap)
-XX:SurvivorRatio=eden/from=eden/to // set eden and from/to space ratio
-XX:NewRatio=old/young // set old to young generation ratio
-XX:+PrintGC // print GC information
-XX:+PrintGCDetails // detailed GC info per region
-XX:+PrintHeapAtGC // print heap before/after GC
-XX:+PrintGCTimeStamps // timestamp GC events
-XX:+PrintGCApplicationConcurrentTime // application concurrent time
-XX:+PrintGCApplicationStoppedTime // application stop time
-XX:+DoEscapeAnalysis // enable escape analysis
-server // run in server mode
-XX:-UseTLAB // disable thread‑local allocation buffers
-XX:+EliminateAllocations // enable scalar replacement
-XX:PermSize=30M // set permanent generation size (JDK 1.6/1.7)
-XX:MaxPermSize=30M // set max permanent generation size (default 64M)
-XX:MaxMetaspaceSize // set metaspace size (JDK 1.8)
-XX:+PrintReferenceGC // print reference queues info
-Xloggc:log/gc.log // output GC logs to file
-verbose:[class|gc|jni] // verbose class, gc, jni info
-XX:+TraceClassLoading // trace class loading
-XX:+TraceClassUnloading // trace class unloading
-XX:+PrintClassHistogram // print class histogram
-XX:+PrintVMOptions // print VM options
-XX:+PrintCommandLineFlags // print command line flags
-XX:InitialHeapSize=10m // set initial heap size
-XX:+PrintFlagsFinal // print all flag values
-XX:+HeapDumpOnOutOfMemoryError // dump heap on OOM
-XX:HeapDumpPath=xxx // path for heap dump
-XX:+UseSerialGC // use serial GC
-XX:MaxTenuringThreshold=xxx // set max tenuring threshold
-XX:PretenureSizeThreshold=xxx // objects larger than this go directly to old generation</code>3. Explanation
-Xmxallocated maximum memory may not match actual usable memory due to alignment algorithms.
If the heap lacks free space, it expands until reaching the maximum heap size.
It is recommended to set the young generation to one‑third or one‑fourth of the heap.
NIO direct memory offers faster access than heap memory but higher allocation cost; suitable for infrequent allocations with frequent access.
The JVM supports Client and Server modes; default is Server. Check mode with
java -version.
Young generation favors copying algorithms; old generation favors mark‑compact.
The old generation uses a card table (bit set) to track references from old to young objects, speeding up GC.
Larger heap increases GC pause time (STW).
Soft and weak references are ideal for optional cache data, reclaimed when memory is low.
4. Garbage Collection Algorithms
Reference counting – cannot handle cyclic references.
Mark‑compact – moves live objects to a contiguous space.
Mark‑sweep – leaves many fragments.
Copying – wastes half of the memory.
Generational – young and old generations.
Region‑based – divides the heap into independent regions for independent reclamation.
5. Copying Algorithm Process
During garbage collection, live objects in the Eden space are copied to an unused Survivor space (e.g., "to"). Objects in the currently used Survivor space (e.g., "from") are also copied to "to". Large or old objects may be moved directly to the old generation; if "to" is full, they also go to the old generation. After copying, the remaining objects in Eden and "from" become garbage and are cleared, while "to" holds the surviving objects.
6. Definition of Garbage Objects
Reachable: reachable from GC roots, thus in use.
Resurrectable: all references released but may be revived in
finalize().
Unreachable:
finalize()has run without resurrection; such objects can be safely reclaimed.
Only unreachable objects are eligible for reclamation.
7. Reference Strengths
Java defines four reference types:
Strong reference – normal references; objects are never reclaimed unless an OOM occurs.
Soft reference – reclaimed only when the JVM is low on memory; implemented by
java.lang.ref.SoftReference.
Weak reference – reclaimed on any GC cycle; implemented by
java.lang.ref.WeakReference.
Phantom reference – the weakest;
get()always returns null; used with a reference queue to track object reclamation and to support
finalize()handling.
Soft, weak, and phantom references reside in the
java.lang.refpackage; the phantom reference is associated with
FinalReferenceto implement
finalize().
Strong references are the usual ones; their objects are reachable and not reclaimed, whereas soft, weak, and phantom references become softly, weakly, or virtually reachable and can be reclaimed under certain conditions.
8. Stop‑The‑World (STW)
The garbage collector pauses all application threads (STW) to ensure a consistent heap state, preventing new garbage creation during collection. This pause makes the application unresponsive until GC completes.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
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.