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:
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.
Advertisement
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.