While we were always told that Java handled himself cleaning the unused objects with its garbage collector, all developers have a day on one of their projects, found that they could be a leak memory with the fatal sentence as: OutOfMemoryException.
This error is particularly difficult to analyze the developments are no longer zero but are often the accumulation of different frameworks, all of which are deployed in an application server.
Fortunately for us, the tools exist to see more clearly, Optimize It was one of the precursors, the most famous are currently YourKit , JProfiler or JProbe
What are commercial quality, but developers do not always have the option to have.
And in the world of free?
Sun offers a few tools: jmap , jhat and VisualVM
Their use can begin the study, but a detailed analysis looks quickly find the needle in a haystack, especially when the boot exceeds the giga byte.
During a recent mission when one of these tools might be needed quickly, a web search I discovered a newcomer to the open source world: Memory Analyzer (MAT) .
Discovering Memory Analyzer
Memory Analyzer is a product in the incubation phase of the projects Eclipse.org, the contributor SAP (a big reference in the world of ERP).
Its objective is to analyze memory dumps (dump format HPROF).
The first version appeared in early 2008, the current version 0.7 was released in December 2008.
Despite this youth, the product is already rich in features, it provides great features:
- Automatic scans for roughing work study of memory
- The possibility of instances with their properties, providing a reference for easy navigation at this level.
- It allows you to query the object format OQL. Very convenient for specific research on a large number of instances.
- The first launch of Memory Analyzer precalculates graphs of consumption. This calculation allows then to have early information about the size of the current object and all objects retained (Retained Heap Size)
- The initial indexing can work faster on large image memory, 512 MB RAM were sufficient to work with a dump of 1.5 GB The use of a 64-bit JVM is possible for very large files.
- Features more traditional route objects, search the point of attachment (GC root), list of objects selected by class or instance ...
Recovery of the dump
Several possibilities:
- Add the JVM parameter:-XX: + HeapDumpOnOutOfMemoryError-XX: = HeapDumpPath
The dump will be created in case of lack of memory, this option is available from the JVM 1.4.2 - Add the java agent HPROF: - agentlib: = heap = dump HPROF, format = b, file =
The dump can be created by a CTRL + BREAK on Windows or a kill -3Unix, this option is available from the JVM since the JVM 1.4.2. - Use jps to get the id of the Java process and jmap-dump: format = b, file =
This tool is available from the Sun JVM 1.5 on Linux and JVM 1.6 for other OS
Start
Memory Analyzer can be used alone as Eclipse RCP or integrated into your Eclipse as a plugin.
Both types of facilities are available at: http://www.eclipse.org/mat/downloads.php
Once this file is obtained, you can run Memory Analyzer
Depending on the size of the dump, it is recommended to give the maximum possible memory by adding-Xmx1024m:
- RCP version in the file MemoryAnalyzer.ini
- Plugin version in the file eclipse.ini
In the plugin version, activate the Memory Analysis perspective
Understand the basics of Garbadge Collector
To understand the results of Memory Analyzer, we must understand the basics of the mechanics of the garbage collector.
Each class instance has a size in mind, this size called "Shallow Heap" consists of the primitive types (int, char ...).
An instance may also have references to other objects that have themselves a size.
Objects can be linked. This is a graph.
There are roots of attachment of the graphs in the JVM, ClassLoader is the case that hold references to static attributes, there are the Threads ...
These roots are called "GC root" in the product.
All instances in memory eventually be attached to a root, if it is not the case, the garbage collector can remove the graph.
The Memory Analyzer is working to launch the first is to analyze each instance in memory.
For each, it analyzes whether his death would have resulted in the disappearance of other objects, if so, he adds, "Retained Heap" the size of the latter. This analysis allows to obtain a dominant tree of "Dominator Tree"
To illustrate this, a simple example with a cache of company that is technically a static attribute of type Map.
public class {CacheEntreprise
private static Map companies = new HashMap ();
...
}
This object contains a reference list of companies that employees who themselves have links to other objects. Objects employees have a reverse lookup on Enterprise, these two objects are linked in both directions:
public class Company {
private List salaries = new ArrayList ();
...
}
public class {Salarie
private Company company;
...
} 
After his analysis, he obtained the dominant tree after it has determined that Enterprise was dominant to Employee: 
To finish all this complexity, Java 5 has made a change on the types of reference instances.
There were strong references "StrongReference"
There are now soft references "SoftReference" The object is referenced, but if the JVM needs memory, it can release the object.
Finally, there are also references light "WeakReference" The object is referenced, as someone else with a strong reference on it, otherwise it is cleaned.
Memory Analyzer is able to work taking into account or not this type of references.
The simplistic application
Using the example simplistic modeling Previous: CacheEntreprise, businesses, workers and address.
The histogram classes shows this: 
We can see objects 2535 Enterprise 60 kb, holding 206 MB of data (employees and addresses)
The CacheEntreprise has no authority here, because it is only a static property that was used.
You can use regular expressions to show only the classes of our project: 
You can search in all of this one particular company with OQL: Example SAP AG
select * from test.mat.Entreprise
Where toString (raisonSociale) = "SAP AG"

One subject in the lower right shows.
The attributes of the object displayed in the left base

By unfolding the subject and following the references, notes that the company weighs 1008 bytes, they are used mostly by three employees: 912 bytes.
Employees have a reverse lookup on the company, Memory Analyzer has not recognized the size of the employee with the calculation dominant / dominated.
The selected employee has a size of 392 bytes used by its attributes and address, but not business related.
One using the route in reverse reference:


We can see that the company is referenced by the three employees with the attribute "company" and the cache that is itself bound by the Class Loader application.
Another way to view the most current way is through "Merge Shortest Paths to GC Roots" 

Another interesting option, "Show Retained Set" displays all the objects selected by the selection:


These examples give an idea of what is possible with this product, with a real project you can imagine it's obviously more complicated.
Here are a few catches automatic reports:
Large consumers of memory: 
Here: The meta given in Spring, Hibernate cache memory HSQLDB and queries
Another interesting report: large consumers by package java

Conclusions
This young product may soon become a must for developers running out of memory.
In use, some of these features exceed these race condition, but it is limited to the analysis in conjunction with memory HPROF.


