[RSS]

How can I fix memory leaks?

The first problem is to identify what is the root problem causing that memory cannot be used effectively. The usual approach for this is to analyze the complete contents of memory when the problem appears, using one of a number of appropriate tools, and ideally then find a solution.

Below are some hints on how to analyze the content of memory:

jmap and built-in dumpers in JDK

Obtain the dump.

If the problem causes OutOfMemoryError, it is possible to customize JVM to provide a memory dump automatically whenever an OutOfMemoryError is thrown. user FAQ about OOME describes what options can be used for this. If you are developing modules, it is a very good idea to set the option -J-XX:+HeapDumpOnOutOfMemoryError in your netbeans.conf.

If the memory leak is not so aggresive to fill all the available memory and cause an OutOfMemoryError, it is still possible to use jmap to generate the same dump. Running full GC before you create this dump can be a good idea as it can strip the size of dump file and remove some unimportant objects from the snapshot. You can do this by turning memory toolbar on (do a right click in toolbar area and check 'memory' item). Repeating this several times can even collect large amounts of data held in various caches throug soft or weak references and make it easier to browse the dump.

Analyze the problem.

Once you have the dump of the heap in a file, it is possible to open it either using jhat. It will start simple webserver and you can use a web browser to see the data. There are many functions starting with lists of classes with numbers of objects and their size, navigation between references, finding of refrence chain from GC root to certain object to. OQL can be used to express more complex queries and run them.

An alternative to a web front-end can be the OQL console as a Swing application. This is also available as a NetBeans module NBJHAT.

Another possibility is to open it with NetBeans profiler and use its .

Documentation for jmap and jhat and other tools is part of the JDK tools documentation. JDK 6 then extends number of platform where these tools can be used.

Profilers and other tools

There are also other tools that can be helpful and provide some useful features.

NetBeans Profiler is enhanced and allows to open heap dumps (those generated by Jmap or similar dumper. Brief overview of heap walker is on the website. Nice feature is search for path from GC root. Another advantage is integration with the rest of IDE and simple navigation to sources.

INSANE is a home grown tools that is useful for analysis of memory content and also can be used in automated tests - so once you have fixed a memory leak, you can write a test that will fail if the memory leak is ever recreated.

OptimizeIt Probably the most appealing feature here is possibility to generate multiple snapshots of heap and analyze their differences. Note that it needs JVMPI so it cannot be used with Java 6. (OK, it can be if you know the trick.) It shows information about amount of memory retained by object (and reachable memory from object). OptimizeIt is not very useful when tracking leaks where classloaders are involved.

DTrace can be used to monitor object allocation and garbage collection. Nice article about using dtrace with hotspot provider is Java and DTrace.

Tips and tricks

Common leaking objects

There are some typical classes where it should be easily possible to tell what is appropriate number of their instances in the memory and if these are leaking there is a serious problem:

  • Projects - it means instance of all subclasses of org.netbeans.api.project.Project
  • Editors (or TopComponents) - it can be useful to check for org.openide.text.QuietEditorPane instances to see if closed editors can release substantial part of associated memory. If the editor component is held it often means that associated editor support is held too linking to parsing data, sidebars providing versioning information and probably also project metadata. It is also possible to look for instance of org.openide.windows.TopComponent if there is some suspicion or better to search for its particular subclasses. Generally there will be always certain numbers of TopComponents.
  • Documents - somewhat related to editors. An important class where you can start is org.netbeans.modules.editor.NbEditorDocument.
  • Top-level windows - not disposed dialog can be a problem as these hold native resources that can be limited in the system.
  • ClassLoader - we need to be very careful and check that classloader created dynamically during runtime can be GC'ed when they are no longer used. Without this the result is OOME signaling that perm gen area is full.
  • CompilationInfo (javac) - related to java infrastructure. An important class where you can start is com.sun.tools.javac.code.Symtab which is singleton in javac instance.

Leaks vs. retained memory

There are two different ways how memory can be wasted: leaks and improper retention of memory.

Leaks are cases when repeated invocation of certain activity creates new set of objects that cannot be reclaimed after activity is finished. The biggest problem is cumulating of these objects that leads to increased memory usage and after long enough time leads to OutOfMemoryError. The nature of this error is that it leaves data structures of an application in undefined state so anything what is executed after this moment may lead to unexpected results.

Retained memory is a memory occupied by objects that were created to serve some purpose but is these objects are held longer than necessary. This may mean that some action has to performed that flushes these objects or that they remain in memory until the end of seesion. The example of former are LRU caches (often holding last component in UI, files or projects). Common example of the latter are resources like parsed bundles or images statically referenced in classes that use them.

-J-Dnetbeans.debug.heap can make profiling easier as it more quickly releases references to collapsed nodes and turns off periodic refresh of filesystems (it is turn off by default anyway).

Once Counters are finalized they should be mentioned here.


Applies to: NetBeans x.x

Platforms: All