Hi Thomas:

Here is a sample application i made to analyze this situation, i do hope it is useful.

// Start of SVGLeakTest.java
////////////////////////////////////////////////
//
// SVGLeakTest.java
// Created By: Andres Toussaint
// Date: June 23, 2004
// Version 1.0
//
////////////////////////////////////////////////

/*
The purpose of this application is to diagnosticate the possible Memory leak
associated with the removal of SVG Image elements in the JSVG Canvas.


To run this file you will need 9 SVG images, one to work as base document
and the other 8 as two sets to be replaced. The idea of this is to have a
heavyweight image and a lightweight image, sort of a full image or template.
Any way, when the four images are replaced, the memory they use is not dealocated.
And when they are placed again, a new instance for each is allocated, so
if you cycle through the replacement over and over, you will notice that the memory
incereases all the time and there is no GC.


After starting the application, click the Load button to load the background, base image.
When the image has finished loading, click on the replace... button to cycle
through the "a.svg" and "a1.svg" images.


The SVG files needed are (the names are hardcoded, since this is a test):
background.svg
a.svg
b.svg
c.svg
d.svg
a1.svg
b1.svg
c1.svg
d1.svg


To better show the memory consumption, ensure the a-d and a1-d1 images are big files (>300Kb)
*/


import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;

import org.apache.batik.dom.svg.*;
import org.apache.batik.dom.*;
import org.apache.batik.dom.util.*;
import org.apache.batik.gvt.*;
import org.apache.batik.gvt.event.*;
import org.apache.batik.swing.*;
import org.apache.batik.swing.gvt.*;
import org.apache.batik.swing.svg.*;
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
import org.apache.batik.bridge.UpdateManager;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.bridge.UpdateManagerListener;
import org.w3c.dom.events.MouseEvent;
import org.apache.batik.util.SVGConstants;

import org.apache.batik.dom.events.*;

public class SVGLeakTest {

public String url = "c:/svgLeak/";
public String fill ="fill-rule:nonzero;clip-rule:nonzero;fill:red;stroke:black;stroke- width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit: 4;";
public String fill2 ="fill-rule:nonzero;clip-rule:nonzero;fill:green;stroke:black;stroke- width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit: 4;";


    public String[] a = {"a.svg", "a1.svg", "10", "10"};
    public String[] b = {"b.svg", "b1.svg", "30", "30"};
    public String[] c = {"c.svg", "c1.svg", "60", "60"};
    public String[] d = {"d.svg", "d1.svg", "90", "90"};
    public String[][] elt = {a,b,c,d};

    public int image = 0;
    public UpdateManager updateM;

    public static void main(String[] args) {
        JFrame f = new JFrame("SVG Leak Test");
        SVGLeakTest app = new SVGLeakTest(f);
        f.getContentPane().add(app.createComponents());

        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        f.setSize(400, 400);
        f.setVisible(true);
    }

    JFrame frame;
    JButton button = new JButton("Load Background...");
    JLabel label = new JLabel();
    JButton buttonR = new JButton("Replace....");

    JSVGCanvas svgCanvas = new JSVGCanvas();

    public SVGLeakTest(JFrame f) {
        frame = f;
    }

    public JComponent createComponents() {
        final JPanel panel = new JPanel(new BorderLayout());

        JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
        p.add(buttonR);
        p.add(button);
        p.add(label);

        panel.add("North", p);
        panel.add("Center", svgCanvas);

        // Set the button action.
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                    try {
                        svgCanvas.setURI(url + "background.svg");
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

// Set the button action.
buttonR.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (image == 0) {
image = 1;
} else {
image = 0;
}
label.setText("The image action is:"+image);
updateM.getUpdateRunnableQueue().invokeLater(new Runnable() {
public void run() {


doDynamicElelements((SVGOMDocument)svgCanvas.getSVGDocument());

                    }
                });
            }
        });

        svgCanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);

// Set the JSVGCanvas listeners.
svgCanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter() {
public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
label.setText("Document Loading...");
}
public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
label.setText("Document Loaded.");
loadExternalImages((SVGOMDocument)e.getSVGDocument());
}
});


svgCanvas.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
public void gvtBuildStarted(GVTTreeBuilderEvent e) {
label.setText("Build Started...");
}
public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
label.setText("Build Done.");
frame.pack();
}
});


svgCanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {
public void gvtRenderingPrepare(GVTTreeRendererEvent e) {
label.setText("Rendering Started...");
}
public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
label.setText("");
updateM = svgCanvas.getUpdateManager();


            }
        });

        return panel;
    }

public void loadExternalImages(SVGOMDocument document) {
SVGOMSVGElement documentElement = (SVGOMSVGElement)document.getDocumentElement();


        String svgNS = "http://www.w3.org/2000/svg";;
        Element theGroupElement = document.createElementNS(svgNS, "g");
        theGroupElement.setAttribute("id", "imgGroup");
        theGroupElement.setAttribute("style", "none");
        documentElement.appendChild(theGroupElement);
        Element imgGroup = documentElement.getElementById("imgGroup");

        for (int i =0; i<elt.length;i++) {

            imgGroup.appendChild(createImage(elt[i][2],
            elt[i][3],
            "30","30",
            elt[i][0],
            new Integer(i).toString(),
            document));
        }
    }

public void doDynamicElelements(SVGOMDocument document){
SVGOMSVGElement documentElement = (SVGOMSVGElement)document.getDocumentElement();
AbstractParentNode imgGroup = (AbstractParentNode)documentElement.getElementById("imgGroup");
SVGOMElement theElement = (SVGOMElement)imgGroup.getFirstChild();


while(theElement!=null){
System.out.println("Found Dynamic Element: "+theElement.getAttribute("uid"));
SVGOMElement theNext = (SVGOMElement)theElement.getNextSibling();
if (theElement.getAttribute("uid")!="buffer"){
System.out.println("Deleting Dynamic Element: "+theElement.getAttribute("uid"));
SVGOMElement toRemove = (SVGOMElement)imgGroup.removeChild(theElement);
EventSupport es = toRemove.getEventSupport();
if (es != null) {
EventListenerList el = es.getEventListeners(SVGConstants.SVG_EVENT_CLICK, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_KEYDOWN, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_KEYPRESS, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_KEYUP, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_MOUSEDOWN, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_MOUSEMOVE, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_MOUSEOUT, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_MOUSEOVER, false);
printList(el);
el = es.getEventListeners(SVGConstants.SVG_EVENT_MOUSEUP, false);
printList(el);
}
toRemove = null;
}
theElement = theNext;
}


        for (int i =0; i<elt.length;i++) {

            imgGroup.appendChild(createImage(elt[i][2],
            elt[i][3],
            "30","30",
            elt[i][image],
            new Integer(i).toString(),
            document));
        }

    }

protected void printList(EventListenerList el) {
if (el != null) {
org.w3c.dom.events.EventListener[] e = el.getEventListeners();
for (int i= 0; i< el.size(); i ++) {
System.out.println(el.toString()+" event:"+e[i].toString());
}
}
}


protected Element createImage(String x, String y, String width, String hgt,
String image, String uid, SVGOMDocument document){
String svgNS = "http://www.w3.org/2000/svg";;
String xlinkNS = "http://www.w3.org/1999/xlink";;
Element img = document.createElementNS(svgNS, "image");
img.setAttributeNS(null, "x", x.toString());
img.setAttributeNS(null, "y", y.toString());
img.setAttributeNS(null, "width", width.toString());
img.setAttributeNS(null, "height", hgt.toString());
img.setAttributeNS(xlinkNS,"xlink:href", image);
img.setAttribute("uid", uid);
return img;
}


    protected Element createRectangle(String x, String y, String width,
    String hgt, String fillColor, String uid, SVGOMDocument document){

        String svgNS = "http://www.w3.org/2000/svg";;
        Element rect = document.createElementNS(svgNS, "rect");
        rect.setAttributeNS(null, "x", x.toString());
        rect.setAttributeNS(null, "y", y.toString());
        rect.setAttributeNS(null, "width", width.toString());
        rect.setAttributeNS(null, "height", hgt.toString());
        rect.setAttributeNS(null, "style", fillColor);
        rect.setAttribute("uid", uid);
        return rect;
    }
}


// end of SVGLeakTest.java



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to