Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Training online: Concurrency, Threading, GC, Advanced Java and more ...
Tips July 2025
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 296 contents
https://www.youtube.com/watch?v=K_vuBOjJtxk
GC Tuning: A Masterpiece in Performance Engineering (Page last updated May 2025, Added 2025-07-28, Author Ram Lakshmanan, Publisher Bulgarian Java User Group). Tips:
- Tuning GC settings can optimize performance without needing any code changes. Effective benefits include: reducing customer-facing response times; reducing computing cost by having the JVMs spend less time on garbage collection; decreasing CPU consumption.
- Key performance indicators for GC tuning: Latency (average pause time); Throughput (cumulative application processing time vs GC activity tine); Footprint (memory and CPU consumption); Response time.
- Enable garbage collection logging on the JVM by passing specific arguments e.g., `-Xlog:gc*:FILE_PATH` for Java 9 and above. GC logging has minimal overhead. GC log formats are not standardized and vary by JVM vendor, Java version, and GC algorithm. These tools can parse and analyze GC logs, providing warnings, recommendations, and KPI summaries.
- GC tuning methodology: Document current JVM arguments and KPIs (average pause time, max pause time, GC throughput percentage); Systematically change JVM arguments (add, remove, increase/decrease values) and document the new KPIs; repeat until targets achieved.
- Remove all existing JVM arguments, start tuning from scratch.
- Disable `System.gc()` calls. `System.gc()` calls typically trigger a full garbage collection event in the JVM, causing unnecessary pauses. Use `-XX:+DisableExplicitGC`.
- Adjust heap size: Increasing or decreasing the heap size (`-Xmx`) can positively impact JVM performance; If GC logs show aggressive full garbage collection, increasing the heap size might reduce frequency and improve throughput; Reducing the heap size can save computing costs.
- Resizing young and old generations within the JVM can have a powerful positive impact on GC performance.
- Choice of GC algorithm: Effective GC algorithms in OpenJDK are Parallel, G1, Shenandoah and ZGC (Serial GC is outdated, CMS is deprecated, Epsilon is a no-op GC); Switching GC algorithms can significantly change performance; Focus on tweaking a curated set of important settings within a chosen GC algorithm rather than all 600+ available arguments.
- Ensure the JVM runs with sufficient system resources (CPU, memory) as a lack of capacity can negatively impact garbage collection.
- Write memory-efficient code: Writing code that creates fewer objects and less garbage will naturally lead to less garbage collection time and improved response times.
https://www.youtube.com/watch?v=Bdj6cX-yPco
Continuous Profiling: The Missing Piece in Your Observability Puzzle (Page last updated July 2025, Added 2025-07-28, Author Mohammed Aboullaite, Publisher Code Remix). Tips:
- The three pillars of observability are: Logs - a timestamped record of events providing information on what happened, when, and often why; Metrics - numerical representation of system data (CPU usage, memory consumption, heap size, thread count, etc), useful for spotting issues (like memory usage spikes) but don't provide the "why" behind issues; Traces - gives the journey of a request through system components, useful for identifying bottlenecks and optimizing request processing time. These need to be correlated to be fully effective, and adding profiling improves identification of the root cause of issues.
- Profiling attempts to understand *why* issues are happening (e.g., what caused a CPU spike). It goes deep into specific code to identify resource consumption.
- Types of profiling include: CPU profiling - which parts of code uses the most CPU; Workload (wall-clock) profiling - which parts of code takes the longest to run (on or off CPU); Allocation profiling - what is consuming memory, why there are many objects, and what is stressing memory; Lock profiling - understand delays or stops in code execution due to locks; Heap profiling - understand what is taking up memory within the heap.
- Continuous profiling needs specific profilers that can continuously collect data rather than at specific events or periods and be low overhead, making it production-friendly (less than 2% overhead).
- Types of profilers: Sampling profiler (statistical profiler) - collects data at regular intervals, higher frequency means more data and CPU impact; Event-based profiler - collects data when specific events are triggered (e.g., cache expiry, lock operations); Instrumenting profiler - requires code changes to instrument specific behaviors; Threshold Profiler - captures data only for outliers (e.g., queries taking longer than a specified time), reducing data volume but not providing the bigger picture.
- Factors influencing overhead of profilers: Sampling Frequency - higher frequency increases CPU overhead; Data Volume - impacts disk space and network overhead; Symbolization Strategy - where the symbol mapping process occurs (on-host vs. centralized backend) impacts CPU, IO, and network overhead; Agent vs. Agentless - agents add overhead by running next to the application; agentless (eBPF) runs within the kernel with lower overhead, but may have security concerns.
https://www.youtube.com/watch?v=lbU625cLYsc
Garbage Collection In Java (Page last updated June 2025, Added 2025-07-28, Author Sagar V Hande, Publisher Scripting with Ease). Tips:
- Minimize Object Creation. Reduce the creation of new objects, especially within loops, to conserve memory.
- Use primitive data types (e.g., int, char) instead of their wrapper classes (e.g., Integer, Character) when possible.
- Avoid Memory Leaks: Be mindful of static references that might hold onto unused objects; Ensure listeners are de-registered when no longer needed; Always release resources like database connections, input/output streams, and file handles, ideally in finally blocks; Utilize finally blocks to ensure that all opened connections (e.g., input/output streams, database connections) are properly closed.
- If you observe frequent garbage collection pauses, consider increasing the heap size.
- OOME: leak related - fix it, but it might just be sizing so check that first; heap related - increase the maximum heap size (-Xmx parameter); Metaspace - increase the maximum metaspace size (-XX:MaxMetaspaceSize parameter); StackOverflowError - increase the stack size using the -Xss parameter.
- Main sizing options: initial heap size -Xms; maximum heap size with -Xmx; initial and maximum size of the young generation -XX:NewSize and -XX:MaxNewSize respectively; the ratio of Eden to survivor spaces can be updated for better performance.
- Choosing a GC algorithm: Serial GC - best for small, single-threaded applications; Parallel GC - default in many JDKs, suitable for high throughput and multi-core CPUs; CMS (Concurrent Mark Sweep) - removed in Java 14, known for low pauses but long full GCs when run long enough; G1GC (Garbage First) - default in Java 9+, offers balanced performance and low pauses; ZGC: for very large heaps and ultra-low pauses.
Jack Shirazi
Back to newsletter 296 contents
Last Updated: 2025-08-28
Copyright © 2000-2025 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/news/newtips296.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us