Next up in our series of developer tools is JMap.
There are plenty of errors or issues that might go wrong with your Java application, but there is one that happens more often than others – OutOfMemoryError, related to Java objects memory issues. Once your application throws one of these, your first target is Java heap memory.
What should you do to grab your Java application’s heap memory details or an object’s memory maps?
Well, the first answer is to use something like JProfiler or YourKit and attach it to the working application. Those tools are the best ones to use during your Java application’s profiling, but those are the paid ones.
Fortunately, the goodies provided with the JDK come to the rescue, in particular, JMap. JMap is a tool that can connect to a running Java process or a remote debug session. It allows us to:
- retrieve general information about the heap, i.e. heap configuration and its usage,
- print histogram of Java objects heap,
- dump Java heap to a file.
Let’s dive into each of JMap’s functionalities.
- Heap detailed configuration information.
➜ bin jmap -heap 1384 Attaching to process ID 1384, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.131-b11 using thread-local object allocation. Parallel GC with 8 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 4294967296 (4096.0MB) NewSize = 89128960 (85.0MB) MaxNewSize = 1431306240 (1365.0MB) OldSize = 179306496 (171.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 67108864 (64.0MB) used = 7472328 (7.126167297363281MB) free = 59636536 (56.87383270263672MB) 11.134636402130127% used From Space: capacity = 11010048 (10.5MB) used = 6976136 (6.652961730957031MB) free = 4033912 (3.8470382690429688MB) 63.36154029482887% used To Space: capacity = 11010048 (10.5MB) used = 0 (0.0MB) free = 11010048 (10.5MB) 0.0% used PS Old Generation capacity = 179306496 (171.0MB) used = 16384 (0.015625MB) free = 179290112 (170.984375MB) 0.009137426900584795% used 4360 interned Strings occupying 316640 bytes.
- Histogram.
➜ bin jmap -histo 1384 num #instances #bytes class name ---------------------------------------------- 1: 1491 10039904 [I 2: 1949 3805008 [B 3: 9980 940552 [C 4: 2325 263264 java.lang.Class 5: 9635 231240 java.lang.String 6: 3730 119360 java.util.concurrent.ConcurrentHashMap$Node 7: 1714 102944 [Ljava.lang.Object; 8: 1583 75984 java.util.zip.Inflater 9: 2334 74688 java.util.HashMap$Node 10: 1729 69160 java.lang.ref.Finalizer 11: 699 61512 java.lang.reflect.Method 12: 3292 52672 java.lang.Object
- Heap dump.
➜ bin jmap -dump:live,file=/tmp/test.bin 1384 Dumping heap to /private/tmp/test.bin ... Heap dump file created
The 3rd point is the most interesting one. Thanks to JMap’s fast creation of heap dump binary file we got a possibility to view the details of our heap without influencing the application’s performance (note the: live option).
Now is the time to analyse your application’s heap. Well, should you use JProfiler/YourKit? Not really, try out the JDK’s JHat tool!