Skip to content

JVM Getting the largest objects in the heap programmatically

How programmatically (from within the java application/agent) do I get a “live” summary of the largest objects in the heap (including their instances count and size)?

Similarly to what Profilers do.

For example, here is a screenshot from JProfiler:

Live objects

Usually I used to work with heap dumps in the cases where I really needed that, but now I would like to figure out how exactly profilers retrieve this kind of information from the running JVM without actually taking a heap dump.

Is it possible to get this kind of information by using the Java API? If its impossible what is the alternative in the native code? Code example would be the best for my needs, because this specific part of java universe is really new to me.

I kind of believe that if I was interested to find the information about some really specific classes I could use instrumentation or something, but here as far as I understand, it uses the sampling so there should be another way.

I’m currently using HotSpot VM running java 8 on linux, however the more “generic” solution I’ll find – the better.

Answer

There is no standard Java API for heap walking. However, there is a HotSpot-specific diagnostic command that can be invoked through JMX:

String histogram = (String) ManagementFactory.getPlatformMBeanServer().invoke(
        new ObjectName("com.sun.management:type=DiagnosticCommand"),
        "gcClassHistogram",
        new Object[]{null},
        new String[]{"[Ljava.lang.String;"});

This will collect the class histogram and return the result as a single formatted String:

 num     #instances         #bytes  class name
----------------------------------------------
   1:          3269         265080  [C
   2:          1052         119160  java.lang.Class
   3:           156          92456  [B
   4:          3247          77928  java.lang.String
   5:          1150          54104  [Ljava.lang.Object;
   6:           579          50952  java.lang.reflect.Method
   7:           292          21024  java.lang.reflect.Field
   8:           395          12640  java.util.HashMap$Node
                       ...

The contents is equivalent to the output of jmap -histo command.

The only standard API for heap walking is the native JVM TI IterateThroughHeap function, but it’s not so easy to use, and it works much slower than the above diagnostic command.