JVM performance tuning guide — heap size configuration, GC selection, Kubernetes CPU throttling, and Prometheus monitoring. Use when optimizing Java applications, configuring the JVM for containers or Kubernetes, choosing the right Garbage Collector (G1, ZGC, ParallelGC), diagnosing memory or latency issues, or understanding Spring Boot executor metrics.
From javanpx claudepluginhub wesleyegberto/software-engineering-skills --plugin javaThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides agent creation for Claude Code plugins with file templates, frontmatter specs (name, description, model), triggering examples, system prompts, and best practices.
Always configure the JVM — default settings were designed for 2000s-era environments.
Use -XX:+PrintFlagsFinal to view all active JVM settings.
Aggressive flags (use with caution):
-XX:+AggressiveHeap
-XX:+AggressiveOpts
The JVM does not know it is running in a container — configure explicitly to avoid inadequate defaults.
| Available Memory | Default Heap |
|---|---|
| Up to 256 MB | 50% |
| 256–512 MB | 126 MB fixed |
| Above 512 MB | 25% |
# Fixed values
-Xms 50m # minimum
-Xmx 1g # maximum
# Container percentage (recommended)
-XX:MaxRAMPercentage=74
Servers:
Containers:
-Xmx: good for well-sized, stable workloads.-XX:MaxRAMPercentage: better for workloads that scale.MinHeapSize == MaxHeapSize (early research suggests this).-XX:+AlwaysPreTouch: locks the defined memory at startup (startup cost, but eliminates runtime memory checks).| Version | Default GC |
|---|---|
| Java 8 | SerialGC or ParallelGC |
| Java 9+ | G1GC (real default) |
| Java 11+ | SerialGC (< 2 CPUs and < 1792 MB RAM) |
| Java 11+ | G1GC or ParallelGC (with sufficient resources) |
Outside container: uses Runtime.availableProcessors()
Inside container: based on cpu.period, cpu.quota or cpu.share
| Heap Size | Recommended GC |
|---|---|
| Up to 2 GB | ParallelGC (best throughput) |
| 2–4 GB | ParallelGC or G1GC |
| Above 4 GB | G1GC or ZGC |
ParallelGC triggers Stop-the-World → impacts latency (tail latency).
CPU requests in Kubernetes define the CPU time available per period.
Processors visible to the JVM in Kubernetes:
| CPU Limit | CPUs for JVM |
|---|---|
| 1–1000m | 1 CPU |
| 1001–2000m | 2 CPUs |
| 2001–3000m | 3 CPUs |
-XX:ActiveProcessorCount=4
Useful for IO-bound applications in containers with 1–2 cores: the JVM increases its internal thread pool, improving the capacity to wait for IO in parallel.
# List Java processes
jps
# Memory histogram by object type
jmap -histo $PID
# ClassLoader statistics
jmap -clstats $PID
executor_queued_tasksShows how many tasks are waiting for execution in the executor queue.
executor_queue_remaining_tasksShows how many free slots remain in the queue.
Spring Boot configuration:
spring:
task:
execution:
pool:
queue-capacity: 100
-XX:+UseStringDeduplicationJVM # reuse equal strings
-XX:+UseSerialGC # single thread
-XX:+UseConcMarkSweepGC # multiple threads
-XX:+UseG1GC # large heap
# Epsilon GC — does nothing (ideal for benchmarks and short-lived processes)
-XX:+UseEpsilonGC
# ZGC — low latency, experimental in this version
-XX:+UseZGC