Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I figure out what is holding on to unfreed objects?

One of our programs is sometimes getting an OutOfMemory error on one user's machine, but of course not when I'm testing it. I just ran it with JProfiler (on a 10 day evaluation license because I've never used it before), and filtering on our code prefix, the biggest chunk both in total size and number of instances is 8000+ instances of a particular simple class.

I clicked the "Garbage Collect" button on JProfiler, and most instances of other classes of ours went away, but not these particular ones. I ran the test again, still in the same instance, and it created 4000+ more instances of the class, but when I clicked "Garbage Collect", those went away leaving the 8000+ original ones.

These instances do get stuck into various Collections at various stages. I assume that the fact that they're not garbage collected must mean that something is holding onto a reference to one of the collections so that's holding onto a reference to the objects.

Any suggestions how I can figure out what is holding onto the reference? I'm looking for suggestions of what to look for in the code, as well as ways to find this out in JProfiler if there are.

like image 666
Paul Tomblin Avatar asked Sep 30 '08 18:09

Paul Tomblin


People also ask

How do you Analyse a memory leak for heap dump?

A dump can be taken on demand (using the jmap JDK utility) or when an app fails with OutOfMemoryError (if the JVM was started with the -XX:+HeapDumpOnOutOfMemoryError command line option). A heap dump is a binary file of about the size of your JVM's heap, so it can only be read and analyzed with special tools.

What happens when Survivor space is full?

If survivor spaces are too large, they will be uselessly empty. At each garbage collection, the virtual machine chooses a threshold number, which is the number times an object can be copied before it is tenured. This threshold is chosen to keep the survivors half full.

How do you analyze out of memory error in Java?

1) An easy way to solve OutOfMemoryError in java is to increase the maximum heap size by using JVM options "-Xmx512M", this will immediately solve your OutOfMemoryError.


2 Answers

Dump the heap and inspect it.

I'm sure there's more than one way to do this, but here is a simple one. This description is for MS Windows, but similar steps can be taken on other operating systems.

  1. Install the JDK if you don't already have it. It comes with a bunch of neat tools.
  2. Start the application.
  3. Open task manager and find the process id (PID) for java.exe (or whatever executable you are using). If the PID's aren't shown by default, use View > Select Columns... to add them.
  4. Dump the heap using jmap.
  5. Start the jhat server on the file you generated and open your browser to http://localhost:7000 (the default port is 7000). Now you can browse the type you're interested in and information like the number of instances, what has references to them, etcetera.

Here is an example:

C:\dump>jmap -dump:format=b,file=heap.bin 3552

C:\dump>jhat heap.bin
Reading from heap.bin...
Dump file created Tue Sep 30 19:46:23 BST 2008
Snapshot read, resolving...
Resolving 35484 objects...
Chasing references, expect 7 dots.......
Eliminating duplicate references.......
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

To interpret this, it is useful to understand some of the array type nomenclature Java uses - like knowing that class [Ljava.lang.Object; really means an object of type Object[].

like image 171
McDowell Avatar answered Sep 21 '22 12:09

McDowell


Try Eclipse Memory Analyzer. It will show you for each object how it is connected to a GC root - an object that is not garbage collected because it is held by the JVM.

See http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/27/automated-heap-dump-analysis-finding-memory-leaks-with-one-click/ for more information on how Eclipse MAT works.

like image 38
Tom Avatar answered Sep 18 '22 12:09

Tom