Hello,
I am still fighting with "dispose()" problems, and I discovered something, which I consider a bug (it appears in 1.5.1 release and in a latest version from CVS head). The problem is when I call method "suspendProcessing()" followed by "dispose()" on JSVGCanvas object, the JSVGCanvas won't be collected by garbage collector. This is somehow connected with UpdateManager ant its RunnableQueue, I think. You may ask why i call dispose() after suspendProcessing() (why not only dispose()). The answer is that I have my own queue of events in my application, and sometimes I get a request to deactivate the SVG screen (suspendProcessing), and soon after that to close it (close). I handle these events one after another (of course AWT in event dispatch thread). The sample code is: MemoryLeakTest.java:
-----------------------------------
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.InputStreamReader; import java.io.Reader; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.net.URL; import java.net.URLConnection; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import org.apache.batik.dom.svg.SAXSVGDocumentFactory; import org.apache.batik.swing.JSVGCanvas; import org.apache.batik.util.XMLResourceDescriptor; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGDocument; public class MemoryLeakTest extends JFrame { JPanel left; JPanel right = new JPanel(); Document doc = null; JSVGCanvas canvas = null; public MemoryLeakTest() { right.setLayout(new BorderLayout()); this.getContentPane().setLayout(new BorderLayout()); this.setSize(new Dimension(1024, 768)); this.setTitle("MemoryTestLeak"); JButton button1 = new JButton("Start"); JButton button2 = new JButton("Stop"); JButton button3 = new JButton("GC"); button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { start(); } }); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stop(); } }); button3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { gc(); } }); left = new JPanel(); left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS)); left.add(button1); left.add(button2); left.add(button3); this.getContentPane().setLayout(new BorderLayout()); this.getContentPane().add(left, BorderLayout.WEST); this.getContentPane().add(right, BorderLayout.CENTER); start(); } private void start() { if (canvas == null) { canvas = new JSVGCanvas(); final ReferenceQueue rq = new ReferenceQueue(); final WeakReference ref = new WeakReference(canvas, rq); new Thread() { public void run() { try { rq.remove(); System.out.println("CANVAS removed "+ref); } catch (InterruptedException e) { e.printStackTrace(); } } } .start(); try { loadDocument(); } catch (Exception e) { e.printStackTrace(); } right.add(canvas, BorderLayout.CENTER); pack(); } } private void stop() { if (canvas!=null) { canvas.suspendProcessing(); canvas.dispose(); canvas = null; doc = null; right.removeAll(); this.invalidate(); this.pack(); System.out.println( Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); } } private void gc() { System.gc(); System.out.println( Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); } private void loadDocument() throws Exception { String stringURL = "file:circle.svg"; Reader reader = null; SVGDocument svgDoc = null; URL url = "" URL(stringURL); URLConnection connection; connection = url.openConnection(); reader = new InputStreamReader(connection.getInputStream()); String parser = XMLResourceDescriptor.getXMLParserClassName(); SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); doc = f.createSVGDocument("file:circle.svg", reader); canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); canvas.setDoubleBufferedRendering(true); canvas.setSize(new Dimension(800, 600)); canvas.setDocument(doc); } public static void main(String[] args) { JFrame frame = new MemoryLeakTest(); frame.pack(); frame.setVisible(true); } } -------------------------------
circle.svg:
---------------------------
<?xml version="1.0" encoding="windows-1250"
standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example circle01 - circle filled with red and stroked with blue</desc> <circle cx="600" cy="200" r="100" fill="red" stroke="blue" stroke-width="10" /> </svg>
------------------------------
After pressing stop and then gc one should see
"CANVAS removed [EMAIL PROTECTED]" message, but it appears
hardly ever.
Regards,
Lukasz
|
- Re: suspendProcessing() and dispose() memory leak Lukasz Matuszczak
- Re: suspendProcessing() and dispose() memory leak Lukasz Matuszczak
- Re: suspendProcessing() and dispose() memory leak Thomas DeWeese
- Re: suspendProcessing() and dispose() memory le... Lukasz Matuszczak
- Re: suspendProcessing() and dispose() memor... Thomas DeWeese
- Re: suspendProcessing() and dispose() m... Archie Cobbs