Master JVM Performance: Memory Structures, Tuning Parameters, and Monitoring Tips

Explore comprehensive JVM performance optimization, covering memory architecture, key tuning flags, garbage collector selection, common OOM scenarios, and essential monitoring tools such as jstack, jstat, JConsole, and VisualVM, with practical examples and code snippets to help you diagnose and resolve memory issues.

Tuanzi Tech Team
Tuanzi Tech Team
Tuanzi Tech Team
Master JVM Performance: Memory Structures, Tuning Parameters, and Monitoring Tips

1. Prerequisites

JVM performance tuning involves trade‑offs and balances across many aspects; it requires a holistic view and objective data rather than guesswork. Before optimizing, understand the following fundamentals:

1. JVM garbage collectors and algorithms 2. Common JVM monitoring tools and commands 3. JVM runtime data areas 4. How to read GC logs 5. Memory allocation and reclamation strategies

2. JVM Memory Structure

JVM memory diagram
JVM memory diagram

The diagram shows that JVM memory consists of stack memory, heap memory, and the permanent generation (or metaspace in newer JDKs).

Young generation = Eden + S0 + S1 Heap = Young generation + Old generation JDK 1.8 and earlier: JVM memory = Stack + Heap + Permanent Generation JDK 1.8 and later: Metaspace replaces Permanent Generation and resides in native memory, so JVM memory = Stack + Heap

1. Stack Memory

Stack memory is private to each thread; a new thread gets its own stack, which is reclaimed when the thread ends. It stores primitive types, object references, and method frames.

Stack memory illustration
Stack memory illustration

2. Heap Memory

Heap memory comprises the young and old generations. Since JDK 1.8 the permanent generation is replaced by metaspace, which uses native memory and does not count toward the heap. The heap is the largest JVM area; all threads share it, and garbage collection operates on the heap.

Heap memory illustration
Heap memory illustration

Eden occupies most of the space, while the two Survivor spaces are smaller, typically in an 8:1:1 ratio.

3. Permanent Generation (Metaspace)

This area stores class metadata and interface information. It is not subject to garbage collection and is released when the JVM shuts down. If metaspace usage keeps growing, check for excessive third‑party JARs, many deployed applications, or dynamically generated proxy classes.

3. Common JVM Parameters

JVM memory limits are bound by the physical memory and the operating system. On 32‑bit systems the usable memory is usually 2‑3 GB, while 64‑bit systems have no such limit.

1. Heap Size Settings

java -server -Xmx4g -Xms4g -Xmn2g -Xss128k
-Xmx4g: Sets the maximum heap size to 4 GB. -Xms4g: Sets the initial heap size to 4 GB (usually equal to -Xmx to avoid re‑allocation after GC). -Xmn2g: Sets the young generation size to 2 GB. Total heap = young + old generation. -Xss128k: Sets each thread’s stack size. Smaller values allow more threads.
java -server -Xmx4g -Xms4g -Xmn2g -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxMetaspaceSize=16m -XX:MaxTenuringThreshold=0
-XX:NewRatio=4: Sets the ratio of young to old generation to 1:4. -XX:SurvivorRatio=4: Sets the Eden to Survivor ratio to 4:1 (each Survivor occupies 1/6 of the young generation). -XX:MaxMetaspaceSize=16m: Limits metaspace to 16 MB. -XX:MaxTenuringThreshold=0: Objects skip Survivor spaces and go directly to the old generation, which can improve throughput for old‑generation‑heavy workloads.

2. Garbage Collector Selection

JVM offers serial, parallel, and concurrent collectors. Serial is suitable only for small data sets; the focus here is on parallel and concurrent collectors.

2.1 Throughput‑Oriented Parallel Collector

java -server -Xmx4g -Xms4g -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy
-XX:+UseParallelGC: Enables the parallel collector for the young generation. -XX:ParallelGCThreads=20: Number of threads used by the parallel collector (usually match CPU cores). -XX:+UseParallelOldGC: Enables parallel collection for the old generation (supported since JDK 6). -XX:+UseAdaptiveSizePolicy: Lets the JVM automatically adjust young generation and Survivor sizes for optimal pause times.

2.2 Latency‑Oriented Concurrent Collector

java -server -Xmx4g -Xms4g -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
-XX:+UseConcMarkSweepGC: Uses the concurrent collector for the old generation. -XX:+UseParNewGC: Uses the parallel collector for the young generation; can be used together with CMS. -XX:CMSFullGCsBeforeCompaction=5: Triggers a full compaction after five CMS cycles to reduce fragmentation. -XX:+UseCMSCompactAtFullCollection: Enables compaction of the old generation during a full GC.

3. Other Auxiliary Configurations

GC log printing:

-XX:+PrintGC Outputs simple GC events, e.g., [GC 118250K->113543K(130112K), 0.0094143 secs] -XX:+PrintGCDetails Outputs detailed GC information, e.g., [GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] ...]

Out‑of‑Memory dump generation:

-XX:+HeapDumpOnOutOfMemoryError Creates a heap dump when OOM occurs. -XX:HeapDumpPath= Specifies the directory for the dump file.

4. Memory‑Leak Diagnosis

Typical OOM categories:

Heap OOM (java.lang.OutOfMemoryError: Java heap space)

Stack depth insufficient (java.lang.StackOverflowError)

Insufficient native threads (java.lang.OutOfMemoryError: unable to create new native thread)

Metaspace OOM (java.lang.OutOfMemoryError: Metaspace)

OOM types diagram
OOM types diagram

1. Metaspace OOM

Metaspace stores class metadata. When OOM occurs, check the metaspace size via monitoring tools and verify that -XX:MaxMetaspaceSize is not set too low.

Metaspace size view
Metaspace size view
Metaspace usage trend
Metaspace usage trend

If metaspace keeps growing, investigate excessive reflective class loading or dynamic proxy generation using -XX:+TraceClassLoading -XX:+TraceClassUnloading.

Class loading trace
Class loading trace

2. Stack Depth Insufficient

Common causes:

Infinite recursive calls

Excessive simultaneous method executions exhausting stack

Methods declaring many local variables

Other stack‑resource‑heavy methods

Too small -Xss configuration

/**
 * VM Args: -Xss128k
 */
public class JavaStackSOF {
    private int stackLength = 1;
    public void stackLeak() {
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args) {
        JavaStackSOF oom = new JavaStackSOF();
        try {
            oom.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length:" + oom.stackLength);
            throw e;
        }
    }
}
stack length:2101
Exception in thread "main" java.lang.StackOverflowError
    at com.sandy.jvm.chapter02.JavaStackSOF.stackLeak(JavaStackSOF.java:13)
    at com.sandy.jvm.chapter02.JavaStackSOF.stackLeak(JavaStackSOF.java:14)
    ...

3. Insufficient Native Threads

On Linux, non‑root users are limited to 1024 threads by default. Increase the limit by editing /etc/security/limits.d/90-nproc.conf. Also, an excessively large -Xss can reduce the maximum thread count.

4. Heap OOM

Typical causes:

Heap size too small

Unexpected traffic spikes

Loading massive data sets into memory at once

Memory leaks

General remediation steps:

1. Obtain a heap dump (recommended via JVM flags or jmap -dump:format=b,file=filename.hprof pid ). 2. Analyze the dump with MAT to locate large objects, potential leaks, and memory usage patterns.

5. JVM Monitoring

Common tools: jstack, jstat, JConsole, jvisualvm. Key metrics include region sizes, full‑GC frequency and duration, young‑GC pause times, and thread counts.

1. jstack

jstack prints thread stack traces for diagnosis, often used together with top .

CPU usage snapshot
CPU usage snapshot

Using top -Hp PID reveals the threads consuming high CPU.

Thread CPU usage
Thread CPU usage

Run jstack PID > log.txt to capture the stack trace for further analysis.

2. jstat

jstat provides runtime statistics.

-class Class loading statistics -compiler JIT compilation statistics -gc Heap garbage‑collection statistics -gccapacity Capacity of young, old, and permanent generations -gcmetacapacity Metaspace size -gcnew Young‑generation GC stats -gcold Old‑generation GC stats -gcutil Garbage‑collection utilization -gccause GC cause information -printcompilation Methods compiled by JIT

Example:

[root@hadoop ~]# jstat -gcutil 3346
S0   S1   E    O    M   CCS   YGC   YGCT   FGC   FGCT   GCT
52.97 0.00 42.10 13.92 97.39 98.02 8 0.020 0 0.000 0.020 0.020

S0: Survivor 0 usage %

S1: Survivor 1 usage %

E: Eden usage %

O: Old generation usage %

M: Metaspace usage %

CCS: Compressed class space usage %

YGC: Young‑gen GC count

YGCT: Young‑gen GC time (s)

FGC: Full‑GC count

FGCT: Full‑GC time (s)

GCT: Total GC time (s)

3. JConsole

JConsole is a JMX‑based visual monitoring tool for local or remote JVMs.

3.1 Remote Monitoring Configuration

-Dcom.sun.management.jmxremote.port=60001 Port for JMX -Dcom.sun.management.jmxremote.authenticate=false Disable authentication -Dcom.sun.management.jmxremote.ssl=false Disable SSL -Djava.rmi.server.hostname=192.168.1.2 Host IP

3.2 Client Connection

Navigate to the JDK bin directory, launch jconsole.exe, choose “Remote Process”, enter the host IP and port, and connect.

JConsole connection dialog
JConsole connection dialog
JConsole monitoring view
JConsole monitoring view

4. jvisualvm

jvisualvm connects similarly to JConsole but offers a richer UI.

jvisualvm interface
jvisualvm interface
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaJVMMemory ManagementGarbage Collectionperformance tuning
Tuanzi Tech Team
Written by

Tuanzi Tech Team

Tuanzi Mobility, Ticketing & Cloud Systems – we provide mature industry solutions, share high‑quality technical insights, and warmly welcome everyone to follow and share.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.