Number: 1150
Title: memory leak in Grappa
Submitter: Mike Thyer
Date: Fri Jun 22 18:20:43 2007
Subsys: Grappa
Version: Grappa 2006-10-10
System: *-*-
Severity: minor
Problem:
Grappa leaks memory and gets progressively slower when using the same Graph object to step through multiple graphs on a GrappaPanel. The problem only occurs when there are default attributes set. The cause seems to be the GrappaNexus observers which are registered for the default attributes but never removed. The list of observers continually grows, and the removal of node-specific attributes becomes progressively slower.

The program below demonstrates the symptoms. Within a minute speed has noticeably dropped and memory usage is continually increases.


import att.grappa.Graph;
import att.grappa.Node;
import att.grappa.Edge;
import att.grappa.Parser;
import att.grappa.GrappaPanel;
import att.grappa.GrappaSupport;
import java.io.StringWriter;
import java.io.StringReader;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

class GrappaMemoryLeak { static Graph graph = new Graph(""); static final int numNodes = 10; static String [] graphStr = new String [numNodes]; static int step=0;

public static void main(String[] args) { SwingUtilities.invokeLater(init); }

static Runnable init = new Runnable () { public void run() { graph.setNodeAttribute("style", "bold"); GrappaPanel panel = new GrappaPanel (graph); panel.setScaleToFit(true); Node [] nodes = new Node [numNodes]; for (int i=0; i != numNodes; i++) { nodes[i] = new Node(graph, "node"+i); for (int j=0; j != i; j++) { new Edge (graph, nodes[i], nodes[j]); } StringWriter writer = new StringWriter (); graph.printGraph(writer); String [] dotArgs = {"dot"}; try { Process dotProcess = Runtime.getRuntime().exec(dotArgs, null, null); GrappaSupport.filterGraph(graph, dotProcess); dotProcess.getOutputStream().close(); } catch (Exception exc) { throw new Error (exc); } graphStr[i] = writer.toString(); }

JFrame window = new JFrame(); window.add(panel); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setLocation (10,30); window.setSize (640,480); window.setVisible(true);

SwingUtilities.invokeLater(loop); } };

static Runnable loop = new Runnable () { public void run() { try { step++; Parser parser = new Parser (new StringReader(graphStr[step%numNodes]), null, graph); parser.parse(); graph.repaint(); } catch (Exception exc) { throw new Error (exc); } SwingUtilities.invokeLater(loop); } }; }


Fix:
commenting out this line in Element.java is a work-around: 1406: attr.addObserver(grappaNexus); but must almost certainly break some feature I'm not using.
Owner: *
Status: *