0

How can I test (what tools do I use) if my reference graph is correct and if objects are released at appropriate times (and there are no memory leaks)?

In my case I'm using Java, but answers related to another languages are welcome too...

closed as unclear what you're asking by gnat, GlenH7, user40980, jwenting, Bart van Ingen Schenau May 13 '14 at 10:22

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • What precisely about weak references do you want to debug? – Neil May 12 '14 at 14:44
  • @Neil Basically it would be nice if there was a way to check if some object can be (or is) collected at given moment, and if not to show where it is still referenced... – mrpyo May 12 '14 at 15:00
  • Unclear what help you need. Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it’s hard to tell what problem you are trying to solve or what aspect of your approach needs to be corrected or explained. See the How to Ask page for help clarifying this question. – gnat May 12 '14 at 16:13
1

Weak references and the Reference class in general can be checked for its reachability by calling isEnqueued(). This is essentially asking if it is scheduled to be removed by the garbage collector (and hence the object which WeakReference points to is about to be nullified by the way WeakReference works).

However, this offers no guarantee that you'll be able to "catch" an object before it gets removed by the garbage collector. It may be that one moment its reference is being utilized in another class and the next, that same instance has already gone out of scope and has since been removed by the garbage collector.

An alternative approach could be to keep a list of (normal) references to instances. When you wish to see if it is the only reference left, create a WeakReference of that instance, and then set the normal reference to null. If it is the only reference left, then isEnqueued() of the WeakReference of that instance should immediately return true. Technically, the garbage collector could run at any moment, even after the very line where you set the normal instance to null, however it is extremely improbable. You could probably force the garbage collector to run prior if you want to further reduce this chance.

The only disadvantage of this approach is, yeah, you're potentially holding a bunch of references to objects that would otherwise be deleted. Though you could remedy this by holding on to a list of SoftReference references to those instances, which is essentially like a WeakReference except that it won't let the reference go unless you absolutely needed more memory.

In this way, you can be sure that this class won't interfere with cleanup, and yet you can still keep track of if an instance would be deleted or not. After you handle the event, however, you should do the responsible thing and remove your SoftReference afterwards thereby allowing your instance to be set free to roam the Elysian Fields.

I hope that helps. Let me know if that answered your question.

  • You mean if WeakReference is the only one left isEnqueued() immediately becomes true? – mrpyo May 12 '14 at 16:20
  • @mrpyo This is my idea, though you should definitely test this theory. The idea is that the virtual machine wastes no time to enqueue items for deletion since it costs practically nothing to do so and waiting until the end of a method could mean the difference between the jvm crashing or not. However, I could be wrong, so I strongly suggest testing it first. – Neil May 12 '14 at 16:27
  • SoftReference does not guarantee data about the object is still available. The Weak/Soft distinction is about performance, not about correctness. If you absolutely need data about the object that has been queued for garbage-collection, you need to handle that in some other way. – Darien May 13 '14 at 18:27
1

If your goal is just to keep a log of when objects are no longer being used, I'd look into ReferenceQueue, which should be more efficient than doing your own constant loops of Reference.isEnqueued() checks.

The choice about what kind of reference to use is trickier, and depends on when you want to be alerted and what kind of information about the object you need available. In particular, I'd also look at PhantomReference as an alternative to WeakReference.

It's a bit roundabout, but you add items to the ReferenceQueue by passing the queue into their constructor, e.g.:

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
WeakReference<Foo> pr = new WeakReference(targetFoo, refq);

In a separate thread, you can loop and wait for when changes occur:

Reference<Object> ref = fooQueue.remove(); // Blocks, poll() is also possible

In this way, you can have code that monitors when certain objects are no longer strongly-reachable.

P.S.: Since the original Foo may be effectively gone, one way to maintain information about it is to make your own subclass of Reference, one that stores information about the Foo so that you can access it later.

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
// Use custom subclass of WeakReference
MyReference<Foo> ref = new MyReference(targetFoo, refq);
ref.setStuff("hello");

// Later, in another thread, etc.

MyReference<Object> ref = (MyReference<Object>) fooQueue.remove();
String msg = ref.getStuff();
  • I think this would be ideal for single references. For multiple references, this may be problematic. – Neil May 13 '14 at 12:36
  • @Neil Don't you mean the reverse? Why would you bother using a ReferenceQueue for a single reference? – Darien May 13 '14 at 18:24
  • Suppose you wanted to know if one of several references stop being used and to do something when that happens. If you block by calling .remove(), it might be that you've passed the moment to deal with other references (of course you could handle it then I suppose). Correct me if I'm wrong. I'm not very familiar with ReferenceQueue. – Neil May 13 '14 at 19:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.