This is the fourth article in the series of articles exploring the tools and techniques for analyzing, monitoring, and improving the performance of Java applications.
The Art of Java Application Performance Analysis and Tuning-Part 1 The Art of Java Application Performance Analysis and Tuning-Part 2 The Art of Java Application Performance Analysis and Tuning-Part 3
The Art of Java Application Performance Analysis and Tuning-Part 5 The Art of Java Application Performance Analysis and Tuning-Part 6 The Art of Java Application Performance Analysis and Tuning-Part 7
In this blog we will continue to look at some of the useful tools for analyzing the Java application programs.
Jmap (Oracle Hotspot Java VM)- Memory Map
jmap prints heap memory details of a given process or core file of a Java application. This tool available in Oracle Hotspot Java VM. Its advanced uses are printing shared object memory maps , heap memory details of core file .
jmap’s important capabilities for memory profiling are
- To print java heap summary
- To print histogram of java live object heap
To print java heap summary
This is the simple way to get the heap usage summary. This can be used to analyze the memory usage of different parts of the Java Heap memory.
jmap -heap <pid> # /usr/local/jdk1.6.0_38/bin/jmap -heap 76693 Attaching to process ID 76693, please wait... Debugger attached successfully. Server compiler detected. JVM version is 20.13-b02 using parallel threads in the new generation. using thread-local object allocation. Concurrent Mark-Sweep GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 53687091200 (51200.0MB) NewSize = 13421772800 (12800.0MB) MaxNewSize = 13421772800 (12800.0MB) OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 16 PermSize = 21757952 (20.75MB) MaxPermSize = 536870912 (512.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 12676169728 (12088.9375MB) used = 1686018912 (1607.9129333496094MB) free = 10990150816 (10481.02456665039MB) 13.30069688382134% used Eden Space: capacity = 11930566656 (11377.875MB) used = 1532793448 (1461.785743713379MB) free = 10397773208 (9916.089256286621MB) 12.847616481226757% used From Space: capacity = 745603072 (711.0625MB) used = 153225464 (146.12718963623047MB) free = 592377608 (564.9353103637695MB) 20.550540864724333% used To Space: capacity = 745603072 (711.0625MB) used = 0 (0.0MB) free = 745603072 (711.0625MB) 0.0% used concurrent mark-sweep generation: capacity = 40265318400 (38400.0MB) used = 4247009064 (4050.2634658813477MB) free = 36018309336 (34349.73653411865MB) 10.54756110906601% used Perm Generation: capacity = 146186240 (139.4140625MB) used = 87710416 (83.64717102050781MB) free = 58475824 (55.76689147949219MB) 59.999091569767444% used
To print histogram of Java live object heap
This is the simple way to get the live object instances in the heap memory. This gives the histogram of class names with number of instances and no. of bytes. This will be useful in OutOfMemomy and high memory usage situations. Using this histogram we can identify
which classes has more number of instances and size.
We can log this output at regular intervals and can analyze to identify objects which are growing.
# /usr/local/jdk1.6.0_38/bin/jmap -histo:live <pid> # /usr/local/jdk1.6.0_38/bin/jmap -histo:live 76693 num #instances #bytes class name ---------------------------------------------- 1: 10362767 1175268016 [C 2: 3779877 651446840 [Ljava.lang.Object; 3: 11373030 454921200 java.lang.String 4: 15872 447443072 [Lnet.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry; 5: 2585762 206860960 org.hibernate.collection.PersistentList 6: 1030813 190528920 [Ljava.util.HashMap$Entry; 7: 3423143 136925720 java.util.ArrayList 8: 1741450 83589600 java.util.HashMap$Entry 9: 46832 76055168 [Lorg.hibernate.jdbc.Expectation; 10: 1147644 73449216 com.test.product.TestJob3 11: 1056207 67597248 com.test.product.TestJob4 12: 685812 65837952 com.test.product.TestJob5 13: 648750 57090000 net.sf.ehcache.Element 14: 842762 53936768 java.util.HashMap 15: 529534 38126448 com.test.product.TestJob2 16: 648749 36329944 net.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry 17: 883157 28261024 java.util.Arrays$ArrayList 18: 96224 23093760 com.test.product.Test1 19: 868136 20835264 java.lang.Long 20: 648750 20760000 net.sf.ehcache.DefaultElementEvictionData 21: 80046 17930304 in.co.test.product.jobs.common.TestJob 22: 114409 16796552 <constMethodKlass> 23: 114409 15570872 <methodKlass> 24: 59639 15299664 [B 25: 188040 15043200 java.util.LinkedHashMap 26: 10634 12314264 <constantPoolKlass> 27: 191278 12241792 java.util.LinkedHashMap$Entry
In above output, top three objects are Character array, Object array and String objects. Normally Character array, String objects tops the list.
Third line shows 11373030 string objects and these objects occupied 454921200 bytes. Observing top 50 rows gives the object usage during high memory usage scenarios.
class name column: the ‘class name’ column consists object class names.
boolean Z byte B char C class or interface Lclassname; double D float F int I long J short S Object Array [Lclassname
Example:
[C is a char[] [S is a short[] [I is a int[] [B is a byte[] [[I is a int[][] [Ljava.lang.String;" is a class name representing a java.lang.String[] array. [Ljava.lang.Object is Object[]
More info at:
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getName%28%29
We can also use Jmap to take heap and core dump and analyze using jhat (or) profilers.
jhat : The jhat command parses a java heap dump file and launches a web-server. jhat enables you to browse heap dumps using your favorite web-browser. This can be used for more advanced heap dump analysis.
Reference:
[1] http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html [2] http://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html [3] http://www.lshift.net/blog/2006/03/08/java-memory-profiling-with-jmap-and-jhat [4] http://www.herongyang.com/Java-Tools/jstack-jmap-JVM-Heap-Dump-Tool.html
Java Profilers
There are many proprietary profiling tools on the market for measuring performance and tracking down performance bottlenecks. These profilers are used to do deep analysis and profiling of java applications.
YourKit Java Profiler (Need License)
YourKit Profiler can be downloaded from http://www.yourkit.com/download/ and documentation is available at http://www.yourkit.com/docs/index.jsp.
You need to get Evaluation license copy from download site. This license key is required to connect client.
To start profiler with java application we need to add profiler agent path to the java command.
#Linux x86, 32-bit Java -agentpath:yjp-11.0.8/bin/linux-x86-32/libyjpagent.so=port=9998 #Linux x86, 64-bit Java -agentpath:yjp-11.0.8/bin/linux-x86-64/libyjpagent.so=port=9998 #Solaris SPARC, 64-bit Java -agentpath:yjp-11.0.8/bin/solaris-sparc-64/libyjpagent.so=port=9998 #IBM AIX PPC, 64-bit Java -agentpath:yjp-11.0.8/bin/aix-ppc-64/libyjpagent.so=port=9998
From Remote Windows Machine
1. start the YourKit Profiler 2. Enter license key details 3. Select 'connect remote server' option 4. Enter 'ServerIP:PortNo' ex: 192.168.9.35:9998 and connect to the server.
Most of the profiler screens are self explanatory and similar to JConsole. For more information and usage pl refer to YourKit Documentation
JProfiler Java Profiler (Need License)
http://www.ej-technologies.com/products/jprofiler/overview.html
There are other monitoring tools like JVisualVM, etc..