Summarizing Java heap utilization with jmap

Java has become one of the most successful languages to hit the IT industry. One of the reasons behind it’s high rate of adoption is that fact that Java manages memory resources for the programmer. This makes programming significantly easier, but introduces additional complexity, since engineers need to size the Java heap and pick a garbage collection algorithm (or in the case of generational collectors, more than one) that best matches an application’s workload. Fortunately, two extremely useful tools allow you to observe the Java heap: the DTrace hotspot provider and the Java jmap utility. In this blog post, I will discuss the jmap utility.

The Java jmap utility provides a number of useful options to summarize heap usage, and get a break down of objects in the new and old generations. To summarize the new and old generations, the jmap utility can be run with the “-heap” option, and the PID of the JVM to summarize (the PID can be acquired by running the jps utility, or by reviewing the ps output):

$ jmap -heap `pgrep java`

Attaching to process ID 5365, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 1.6.0_01-b06

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 1073741824 (1024.0MB)
   NewSize          = 268435456 (256.0MB)
   MaxNewSize       = 268435456 (256.0MB)
   OldSize          = 805306368 (768.0MB)
   NewRatio         = 7
   SurvivorRatio    = 6
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 88080384 (84.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 234881024 (224.0MB)
   used     = 102062424 (97.33431243896484MB)
   free     = 132818600 (126.66568756103516MB)
   43.452818053109304% used
Eden Space:
   capacity = 201326592 (192.0MB)
   used     = 94318424 (89.94905853271484MB)
   free     = 107008168 (102.05094146728516MB)
   46.84846798578898% used
From Space:
   capacity = 33554432 (32.0MB)
   used     = 7744000 (7.38525390625MB)
   free     = 25810432 (24.61474609375MB)
   23.07891845703125% used
To Space:
   capacity = 33554432 (32.0MB)
   used     = 0 (0.0MB)
   free     = 33554432 (32.0MB)
   0.0% used
concurrent mark-sweep generation:
   capacity = 805306368 (768.0MB)
   used     = 15032688 (14.336288452148438MB)
   free     = 790273680 (753.6637115478516MB)
   1.8667042255401611% used
Perm Generation:
   capacity = 50577408 (48.234375MB)
   used     = 30285240 (28.88225555419922MB)
   free     = 20292168 (19.35211944580078MB)
   59.87898786746842% used

The jmap output contains the size of eden (the place where new objects are created), each survivor space, the old generation and the permanent generation. If you aren’t familiar with the generations that are used in modern JVMs, you might want to take a look at Tony Printezis’ article on this topic.

In addition to printing summary data, jmap can also be used to display the objects in the heap.

$ jmap -histo `pgrep java` |more

num   #instances    #bytes  class name
--------------------------------------
  1:    224437    27673848  [C
  2:     38611    23115312  [B
  3:     47801    12187536  [I
  4:    208624     8344960  java.lang.String
  5:     45332     6192904  <constMethodKlass>
  6:     45332     5450864  <methodKlass>
  7:      3889     4615536  <constantPoolKlass>
  8:     45671     4193136  [Ljava.lang.Object;
  9:     66203     3222312  <symbolKlass>
 10:      3889     3192264  <instanceKlassKlass>
 11:      3455     2999296  <constantPoolCacheKlass>
 12:     19754     1106224  java.nio.HeapCharBuffer

< ..... >

This summary contains the type of each object (e.g., “[C” would refer to arrays of characters), the number of objects of each type as well as the total number of bytes these objects take up in the heap. Jmap additionally allows you to filter the output to display only the live objects:

$ jmap -histo:live 698

num   #instances    #bytes  class name
--------------------------------------
  1:     45256     6185464  
  2:     45256     5441744  
  3:      6899     5201176  [B
  4:      3851     4577776  
  5:     29133     4259592  [C
  6:     66069     3213448  
  7:      3851     3169464  
  8:      3417     2970112  
  9:     29714     1188560  java.lang.String
 10:      1553      745224  
 11:      4161      732336  java.lang.Class

< ..... >

There are also jmap options to dump the heap to a file, display the contents of the permanent generation and view obejcts that are awaiting finalization. Jmap is an incredibly useful tool, and in my next blog post I will show how the DTrace hotspot provider can be used to dig into object allocation in much more detail.

12 Comments

Balkrishan Nagpal  on October 29th, 2007

This is a quite a useful information as i was not aware of such a tool, but i would rather love to see the description about some tool which is also available for windows, because i think jmap is only available for linux users. So if you can please provide the information about a tool which has more or less the same functionality as the jmap but is also available for windows. I would also like id you can provide the link for that tool for downloading.

dean ross-smith  on October 29th, 2007

thanks for this. We have a couple of ejb’s that “leak” memory and this should help keep track of things.

Rainer Jung  on November 2nd, 2007

jmap is part of the 1.6 JDK for Windows.

Joseph  on November 5th, 2007

buddy
this is quite useful..thanks. Keep posting these useful things.

andrew  on June 13th, 2008

Jmap is part of the 1.6 JDK but does not have the -heap option and doesn’t seem to work when using histo (at least for me, I always get a message about not having enough space)

Tanya  on February 19th, 2009

Excellent article. Thanks!

Ajay  on October 25th, 2010

Excellent!!!
Very informative, Thank you!!

Mohammed Ali  on December 23rd, 2010

Thanks a bunch, very informative. Jmap did worked for me to quickly view some leaks under jdk1.6 and tune app accordingly…

Jacques Le Roux  on November 21st, 2011

Thanks, I was unware of the live sub-option.

Fabian  on December 1st, 2011

Very Informative.Explained Well.

Tried -heap option on windows,never got any out put.But this worked with Linux.

C:\Oracle\Middleware\jdk160_21\bin>jmap.exe -heap ‘grep java’
Usage:
jmap -histo
(to connect to running process and print histogram of java object heap
jmap -dump:
(to connect to running process and dump java heap)

dump-options:
format=b binary default
file= dump heap to

Example: jmap -dump:format=b,file=heap.bin

Sunil  on July 13th, 2012

Can I use jmap without having java, I just have jre 1.6 on my machine and wants to see memory heap for an application.
Please reply ASAP. thanks

Bipul  on September 13th, 2012

Exactly what i need .
Thanks a lot.

Leave a Comment