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 June 2019
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 223 contents
https://www.youtube.com/watch?v=JoQN4xoXY5Y
Quickly Analysing A Heap Memory Leak (Page last updated May 2019, Added 2019-06-30, Author Jack Shirazi, Publisher Devoxx). Tips:
- The methodology for analyzing memory leaks is four steps: 1. Do I have a leak (and does it needs fixing - use gc logs to see); 2. What is leaking (instances of which classes - compare two heap histograms separated by enough time to see the leak); 3. What is keeping the objects alive (what instances in the app - you need a heap dump to find these); 4. Where is it leaking from (the code where the objects are created and/or assigned - any memory profiler which can sort on GC generations and provide object creation traces).
- You can identify if you have a leak by scanning garbage collection logs and identifying the value of the heap used AFTER full GCs. If those values are consistently increasing, you have a leak. So ensure that you have GC logging on. Finding the heap used after full GCs can be subtle for concurrent GC algorithms, but using a gc logs analyzer such as GCViewer often makes it straightforward (it tends to be visually obvious).
- Heap histograms can be generated by
jmap -histo:live PID
and although this operation impacts the JVM performance, it's much more lightweight than getting a full heap dump. Comparing histograms over time is an easy way to identify the classes of leaking objects.
- To find what is keeping an object alive, you need a heap dump and a heap dump analyzer. Find the roots holding on to the leaking memory (often a large memory chunk easily identified) and find your application instances which are holding the objects and keeping them alive.
- A memory profiler which can sort on GC generation counts and also provides object creation traces let's you find where in the code the leaking objects are being created or assigned. A GC generation count is NOT the age of the objects of a class, it is the number of different ages of objects of a class, where the age is the number of GCs the object has survived. So if there are two objects alive of class X, one which has survived 93 GCs and the other 51 GCs, this is a generation count of 2. If there were a third object which had also survived 51 GCs, the generation count would still be 2. Leaking objects will have a high generation count, all other objects (after Full GCs) will have low generation counts.
https://www.youtube.com/watch?v=9Cnm2lFBe0I
Exploring Java Heap Dumps (Page last updated November 2018, Added 2019-02-25, Author Ryan Cuprak, Publisher Devoxx). Tips:
- Memory leaks have many reasons, some less common are: faulty clone methods; duplicate singletons; cache logic bugs.
- NetBeans (open source) profiler has a profiler API which can be used standalone - https://github.com/apache/incubator-netbeans/tree/master/profiler/lib.profiler/src/org/netbeans/lib/profiler/heap using HeapFactor.createHeap(). Note some profiler calls are slow - prefer Javadoc "Speed: normal" calls. Note the API itself doesn't cache the heap dump into memory, but you could inadvertently do that so be careful.
- Heap dumps can be generated with -XX:+HeapDumpOnOutOfMemoryError, jmap, jshdb, jcmd, cntrl-break, and from the HotspotDiagnostic platform mbean both programmatically or via any JMX client.
- Analyse heaps from gcroots, threads, or class types. Roots are: classes (loaded by classloader), thread, stack local, monitor, JNI reference, something held by the JVM. Generally it's best to filter out internal JVM classes since these won't be causing the leak.
- When processing large heaps, you might need to cache intermediate analyses on disk - and make sure you note which objects have been processed to avoid looping in the same set of objects.
- Heap processing is IO bound
Jack Shirazi
Back to newsletter 223 contents
Last Updated: 2024-09-29
Copyright © 2000-2024 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/newtips223.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us