Forums

Full Version: Memory Leak when adding many graphs
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have an Eclipse Rich Client Application which has an embedded Prefuse display inside an AWT_SWT view.

The Prefuse Display is linked through some event mechanisms to listen to changes to the model of my application. I have noticed that there is a gradual memory leak every time I am updating my screen. I believe I have narrowed this down to the Prefuse source.

First, I was curious if any of the changes recommended in this developer's blog have been addressed:

To refresh my prefuse display I am calling:
graph.clear(); //Clears the prefuse Graph Model
addTuplesToGraph(); //Refreshes graph tuples


//getVisualization() returns m_vis of prefuse.Display
getVisualization().reset(); //
getVisualization().add("graph", graph);

//_defaultRendererFactory was previously created and is cached for refresh
getVisualization().setRendererFactory(_defaultRendererFactory);

//Then call my actions for coloring and layout
getVisualization().run(ACTIONLIST_COLORS);
getVisualization().run(ACTIONLIST_LAYOUT);



And that's it. Is it possible that going about my refresh above is causing this memory leak?

I suppose it may be possible to update the existing graph model, rather than replacing it on each refresh; however, this is an undesirable pattern at the moment. This is because I may not know every individual change (command stack) that occurred to my application model that needs to be sequentially applied to the prefuse Graph model, so a full refresh solves that immediate issue.
I wish that guy had listed the source for his changes so we wouldn't have to rethink it.

This is a very serious problem. Just modify the RadialGraphView demo to instantiate over and over. Caplow! Out of memory.

RadialGraphView gview = null;

for (int i = 0; i < 1000; i++) {
gview = new RadialGraphView(g, label);
}
Visualization vis = gview.getVisualization();
Indeed. I added a post for this in SourceForge.

For the time being, I actually reworked my implementation to not call:

* graph.clear()
* I no longer change the graph tuples.
* I propagate all atomic model changes from my internal model to my Prefuse graph.

This was undesirable, but I did remove the memory problem.

I did take a day and go through the prefuse source code to look at how to patch up the leaks. There are definitely some collections that do not get cleared, or object handles that are not dropped in some of the classes (no GC!). I ran out of time, however, and decided to work with what I have with the bug listed in SourceForge.
I'm glad that worked for you. Unfortunately for me, I have a varying number of separate displays going at once . . .visualizing hundreds of graphs at once sometimes, but never a specific number.

I guess I need to have a graph pool so that a fixed number of graphs can be reused . . . only allocating when I need more.

So you are saying that you remove nodes and edges manually to a graph that is already registered to a visualization?

If that is so, I was doing something like that for a different reason once and came across a race condition.

I think there was a notification that rippled through the cascading tables. there's a fire event before it starts, but nothing to let threads know that the cascading model is finished updating. . . . or I don't understand any of that part, either.
Reference URL's