Wednesday, September 24, 2014

Heap Analysis using Eclipse Memory Analyzer

Download Eclipse Memory Analyzer from Download Link (Click on the Download link)

The Memory Analyzer is able to work with HPROF binary heap dumps, IBM system dumps (after preprocessing them), and IBM portable heap dumps (PHD) from a variety of platforms.
Typical information which can be found in heap dumps (once more - depending on the heap dump type) is:
  • All Objects - Class, fields, primitive values and references
  • All Classes - Classloader, name, super class, static fields
  • Garbage Collection Roots - Objects defined to be reachable by the JVM
  • Thread Stacks and Local Variables - The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects
What do  we have in a heap dump:
 
A heap dump is a snapshot of the memory of a Java process at a certain point of time. There are different formats for persisting this data, and depending on the format it may contain different pieces of information, but in general the snapshot contains information about the java objects and classes in the heap at the moment the snapshot was triggered. Usually a full GC is triggered before the heap dump is written so it contains information about the remaining objects.
The Memory Analyzer is able to work with HPROF binary heap dumps, IBM system dumps (after preprocessing them), and IBM portable heap dumps (PHD) from a variety of platforms.
Typical information which can be found in heap dumps (once more - depending on the heap dump type) is:
  • All Objects
    Class, fields, primitive values and references
  • All Classes
    Classloader, name, super class, static fields
  • Garbage Collection Roots
    Objects defined to be reachable by the JVM
  • Thread Stacks and Local Variables
    The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects
A heap dump does not contain allocation information so it cannot resolve questions like who had created the objects and where they have been created.
 
Launch the application - Start your application with Java 6, then start <jre6>/bin/jconsole.exe and select the running application (in this case Eclipse).
 


Then, select the operation dumpHeap from the com.sun.management.HotSpotDiagnostic MBean. The first parameter p0 is the full path to the heap dump file. Make sure you give it the file extension .hprof. The second parameter p1 should be left at true as we are only interested in live objects. 
 
 
Click on File -> Open Heap Dump

 


 
On the right, you'll find the size of the dump and the number of classes, objects and class loaders.
Right below, the pie chart gives an impression on the biggest objects in the dump. Move your mouse over a slice to see the details of the objects in the object inspector on the left. Click on any slice to drill down and follow for example the outgoing references.
 
Shallow Size: Shallow Size is the memory consumed by one object.  An object needs 32 or 64 bits (depending on the OS architecture) per reference, 4 bytes per Integer, 8 bytes per Long, etc. Depending on the heap dump format the size may be adjusted (e.g. aligned to 8, etc...) to model better the real consumption of the VM. 
 
Retained set of X is the set of objects which would be removed by GC when X is garbage collected.
Retained heap of X is the sum of shallow sizes of all objects in the retained set of X, i.e. memory kept alive by X.
Generally speaking, shallow heap of an object is its size in the heap and retained size of the same object is the amount of heap memory that will be freed when the object is garbage collected.
The retained set for a leading set of objects, such as all objects of a particular class or all objects of all classes loaded by a particular class loader or simply a bunch of arbitrary objects, is the set of objects that is released if all objects of that leading set become unaccessible. The retained set includes these objects as well as all other objects only accessible through these objects. The retained size is the total heap size of all objects contained in the retained set.
 
 
The Memory Analyzer displays by default the retained size of individual objects. However, the retained size of a set of objects - in this case all instances of a particular class - needs to be calculated.
To approximate the retained sizes for all rows, pick Calculate retained size icon from the tool bar. Alternatively, select a couple rows and use the context menu.
 
Select calculate retained sizes from the tool bar
 
Using the context menu , you can drill-down into the set of objects which the selected row represents. For example, you can list the objects with outgoing or incoming references. Or group the objects by the value of an attribute. Or group the collections by their size. Or or or...
  
One thing that makes the Memory Analyzer so powerful is the fact that one can run any action on any set of objects. Just drill down and slice your objects the way you need them. 

  Drill down via the context menu
 
Another important feature is the facility to group any histogram by class loader, packages or superclass .
 
Group the histogram by class loader or package via the tool bar
   
Any decent application loads different components by different class loaders. The Memory Analyzer attaches a meaningful label to the class loader - in the case of OSGi bundles it is the bundle id. Therefore it becomes a lot easier to divide the heap dump into smaller parts.
 

Analyze Class Loader

Class loaders load classes into the memory of the JVM. When analyzing the heap, class loaders are very important for two reasons: First, applications typically load components using separate class loaders. Second, the loaded classes are usually stored in a separate space (e.g. the perm space) which can also be depleted.

Class Loader Explorer

To get an overview, run the Query Browser > Java Basics > Class Loader Explorer inspection on the heap dump.
  • The Memory Analyzer attaches a meaningful label to the class loader - in the case of OSGi bundles it is the bundle id. Looking out for duplicate entries!
  • Next to the class loader name, the table contains the defined classes and the number of live instances. If one and the same component is loaded multiple times, the number of live instances can indicate which class loaders is more alive and which one should be garbage collected.
 
Class Loader Explorer
 
 
Histogram grouped by class loader
 
Grouping the histogram by packages allows to drill-down along the Java package hierarchy.
 
Histogram grouped by packages
 
Grouping the histogram by superclass provides an easy way to find for example all the subclasses of java.util.AbstractMap, etc...
 
 
Histogram grouped by superclass
 
Concept of Domination Tree: It is useful to determine which objects are taking major part of heap memory and dependencies within the objects can be easily identified.
 
for e.g. If we have 2 objects (A&B), if all paths going to B needs to go via A then A is called the parent of B.
 
Memory Analyzer provides a dominator tree of the object graph. The transformation of the object reference graph into a dominator tree allows you to easily identify the biggest chunks of retained memory and the keep-alive dependencies among objects. Bellow is an informal definition of the terms.
An object x dominates an object y if every path in the object graph from the start (or the root) node to y must go through x.
The immediate dominator x of some object y is the dominator closest to the object y.
A dominator tree is built out of the object graph. In the dominator tree each object is the immediate dominator of its children, so dependencies between the objects are easily identified.
The dominator tree has the following important properties:
  • The objects belonging to the sub-tree of x (i.e. the objects dominated by x ) represent the retained set of x .
  • If x is the immediate dominator of y , then the immediate dominator of x also dominates y , and so on.
  • The edges in the dominator tree do not directly correspond to object references from the object graph.
 
The Leak Report
The Memory Analyzer can inspect the heap dump for leak suspects, e.g. objects or set of objects which are suspiciously big.
  
Run the leak report