Monday, November 24, 2014

Heap Analysis

Heap Histogram

The easiest way to analyse which objects consume the most of your memory is via heap histograms. 

Heap histogram can be obtained by running jcmd (here with process 875)
>jcmd 875 GC.class_histogram

num     #instances         #bytes  class name ---------------------------------------------   
1:        789087       31563480  java.math.BigDecimal   
2:        237997       22617192  [C   
3:        137371       20696640  <constMethodKlass>   
4:        137371       18695208  <methodKlass>   
5:         13456       15654944  <constantPoolKlass>   
6:         13456       10331560  <instanceKlassKlass>   
7:         37059        9238848  [B 

Klass related data are often at the top of the list, and so that strings or character arrays

Similar output can be obtained by running jmap command
>jmap -histo:live 875

where :histo suffix is used to force GC so that dead objects could be removed from histogram

Heap histogram are quite small so don't be shy introducing them into your integration tests

Heap Dumps

For a deeper analysis of live objects heap dumps should be obtained. To generate heap dump from a command line, run following command:
> jcmd PID GC.heap_dump  /path/to/dump/heap_dump.hprof

or
>jmap -dump:live, file=/path/to/dump/heap_dump.hprof PID

Such obtained heap dump can be analysed using tools like:
jhat - analysis dump and runs a small http server to let you see results

mat - more sophisticated heap analysis tool with better queries support and reporting

These programs will give you information about objects: Retained Size, Shallow Size, Deep Size

Retained Size - this is the object size + referenced object sizes included (but excluding shared objects i.e. if the referenced objects is referenced from another object, its size won't be included here)
Shallow Size - this object size + reference pointer sizes i.e. 4 or 8 bytes)
Deep Size - this is the object size + referenced objects sizes included + shared object sizes included