Shizam
Shizam

Reputation: 9672

How to tell when a Java object's memory is released?

I have a Swing browser application with a bug that as I add/remove to/from the GUI the memory isn't released for those objects and I'm trying to track down what is holding onto them. Problem is I don't know how to tell when something has actually be fully released from memory.

Is there a way to tell if an object has been released from memory? I'm used to Objective-C where there are several ways to tell.

Thanks

Upvotes: 6

Views: 1675

Answers (4)

Justin Ardini
Justin Ardini

Reputation: 9866

Edit:

As NoozNooz42 has pointed out, a PhantomReference can do everything a finalizer can, without the problems finalizers present. So, I encourage using PhantomReferences over extending finalize(). I am keeping my original post in tact, since I think Java programmers should at least know that finalize() exists.

Original Post:

Every Java class has a finalize() method that gets run when no other Objects hold a reference to that class. You can extend this method like so:

protected void finalize() throws Throwable {
    try {
        // Do whatever you want
    } finally {
        super.finalize();
    }
}

By doing so, you can figure out if anything holds a reference to the Objects in question. Just make sure you always call super.finalize() if you use this approach.

Reference on finalization:

http://java.sun.com/developer/technicalArticles/javase/finalization/

Upvotes: 3

NoozNooz42
NoozNooz42

Reputation: 4338

You can't really do it in Java. All the answers mentioning finalizers are really not what you're after.

The best you can do is enqueue a PhantomReference in a ReferenceQueue and poll until you get the reference.

final ReferenceQueue rq = new ReferenceQueue();
final PhantomReference phantom = new PhantomReference( referenceToObjectYouWantToTrack, rq );

You want to read Peter Kofler's answer here (it explains what a PhantomReference is):

Have you ever used Phantom reference in any project?

Very interesting read here:

http://www.kdgregory.com/index.php?page=java.refobj

Basically, I'm using a PhantomReference in a project where a very special kind of cache needs to be computed once, when the software is installed. To efficiently compute this (disk-based) cache, a gigantic amount of memory is needed (the more the better). I'm using a PhantomReference to track "nearly exactly" when that gigantic amount of memory is released.

Upvotes: 6

Johannes Wachter
Johannes Wachter

Reputation: 2735

There are multiple ways of detecting memory leaks. Here the three I'm currently thinking of:

  1. Attaching a Profiler to your application (Netbeans or Eclipse TPTP should be useful here)
  2. Making a heap dump and analyze (with Eclipse Memory Analyzer) what instances of a class are held in memory by which other instances.
  3. Attaching VisualVM to track Garbage Collection status.

Upvotes: 3

Brian S
Brian S

Reputation: 5056

Try YourKit. It's a Java profiler which can show you your memory usage and what the heck is going on. IIRC, the free trial can integrate with Eclipse and has all of the paid version's features (it just has a time limit).

Upvotes: 1

Related Questions