You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by "Baron, Randy {PRG~Basel}" <RA...@Roche.COM> on 2003/05/05 12:06:46 UTC

JSVGCanvas disposal / memory leak

Hi,
   We've been trying to find a way to dispose of a JSVGCanvas after it's
finished being displayed in order to solve a memory leak problem.  We
added a kind of 'disposal' method (see below) to try to cut any ties it
might have to other objects but it apparently is still missing nulling
out something since the memory is not released.  Maybe the order that
the methods are called should be different?  Does anyone out there know
of other ways of disposing of a JSVGCanvas? Or disposing of the
RunnableQueue? It looks like that is also a key piece that keeps the
memory from being released (when the canvas is set to ALWAYS_STATIC the
memory leak is gone, but it needs to be ALWAYS_DYNAMIC for udating I
believe).
  Any ideas, comments, anecdotes,...?

-Randy


Snippet from a class that extends JSVGCanvas:
    public void nullOut() {
        ToolTipManager ttipman = ToolTipManager.sharedInstance();
        ttipman.unregisterComponent(this);         
        this.releaseRenderingReferences();
 
this.removeJGVTComponentListener((JGVTComponentListener)aListener);
        this.stopProcessing();
        if(this.getUpdateManager() != null) 
            this.getUpdateManager().getBridgeContext().dispose();
        try {
            this.resumeProcessing();
        }catch(IllegalStateException ex) {
            log.info(ex.getMessage());
        }
        flushSVGDocument();
        doc.removeChild(doc.getDocumentElement());
        this.removeGVTTreeRendererListener(this.gvttreeRenAd);
        if (svgDisplay != null) svgDisplay.nullOut();
        aListener = null;
        this.evListener = null;
        this.deselectAll();
        this.removeAll();
        this.gvttreeRenAd = null;
        this.bridgeContext = null;
        this.svgRoot = null;
        this.svgDisplay = null;
        this.doc = null;
        this.geneData = null;
        this.listener = null;
        this.listenerList = null;
    }

-------------

(some variables above refer to class variables:
    private Document doc;
    private SVGFormatter svgDisplay;
    private Element svgRoot;
    private GeneToSVG geneData;
    private GVTTreeRendererAdapter gvttreeRenAd;
    private EventListener evListener;
    private Listener aListener;   
)



p.s. flushSVGDocument() thanks to
http://koala.ilog.fr/batik/mlists/batik-users/archives/msg03223.html


//----------------------------------------------------------------------
----
// Flush SVG document
//----------------------------------------------------------------------
----
    public void flushSVGDocument() {
      Node childNode = null;
      SVGDocument oSVGDocument = getSVGDocument();

      if (oSVGDocument != null) {
        SVGSVGElement s = oSVGDocument.getRootElement();
        removeNodes(s);
      }
      System.gc();
    }

//----------------------------------------------------------------------
----
// Flush node
//----------------------------------------------------------------------
----
    private void removeNodes(Node n) {
      Node childNode = null;
      Node prevChildNode = null;

      for (childNode = n.getLastChild(); childNode != null;) {
        if (childNode.hasChildNodes()) {
          removeNodes(childNode);
        }
        prevChildNode = childNode.getPreviousSibling();
        if (!(childNode instanceof SVGOMPathElement)) {
          n.removeChild(childNode);
        }
        childNode = null;
        childNode = prevChildNode;
      }
      n = null;
    }




---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


RE: JSVGCanvas disposal / memory leak

Posted by Thomas E Deweese <th...@kodak.com>.
>>>>> "BR" == Baron, Randy {PRG~Basel} <RA...@Roche.COM> writes:

RB> Hi, We've been trying to find a way to dispose of a JSVGCanvas
RB> after it's finished being displayed in order to solve a memory
RB> leak problem.  We added a kind of 'disposal' method (see below) to
RB> try to cut any ties it might have to other objects but it
RB> apparently is still missing nulling out something since the memory
RB> is not released.  Maybe the order that the methods are called
RB> should be different?  Does anyone out there know of other ways of
RB> disposing of a JSVGCanvas? Or disposing of the RunnableQueue? It
RB> looks like that is also a key piece that keeps the memory from
RB> being released (when the canvas is set to ALWAYS_STATIC the memory
RB> leak is gone, but it needs to be ALWAYS_DYNAMIC for udating I
RB> believe).  Any ideas, comments, anecdotes,...?

    I would add:

    updateManager = null;

    stopping the updateManager doesn't purge it's references.
(although loading the next document should remove the JSVGCanvas's
reference to the previous UpdateManager).
    
    Also I would also suggest investing in a leak tracking tool (you
can find objects in the heap by type and then find out who is pointing
at them), they aren't that expensive. Unfortunately, I suspect one
would probably would have paid for it's self in the time you have
spent here.

RB> -Randy


BR> Snippet from a class that extends JSVGCanvas: public void
BR> nullOut() { ToolTipManager ttipman =
BR> ToolTipManager.sharedInstance();
BR> ttipman.unregisterComponent(this);
BR> this.releaseRenderingReferences();
 
BR> this.removeJGVTComponentListener((JGVTComponentListener)aListener);
BR> this.stopProcessing(); if(this.getUpdateManager() != null)
BR> this.getUpdateManager().getBridgeContext().dispose(); try {
BR> this.resumeProcessing(); }catch(IllegalStateException ex) {
BR> log.info(ex.getMessage()); } flushSVGDocument();
BR> doc.removeChild(doc.getDocumentElement());
BR> this.removeGVTTreeRendererListener(this.gvttreeRenAd); if
BR> (svgDisplay != null) svgDisplay.nullOut(); aListener = null;
BR> this.evListener = null; this.deselectAll(); this.removeAll();
BR> this.gvttreeRenAd = null; this.bridgeContext = null; this.svgRoot
BR> = null; this.svgDisplay = null; this.doc = null; this.geneData =
BR> null; this.listener = null; this.listenerList = null; }

BR> -------------

BR> (some variables above refer to class variables: private Document
BR> doc; private SVGFormatter svgDisplay; private Element svgRoot;
BR> private GeneToSVG geneData; private GVTTreeRendererAdapter
BR> gvttreeRenAd; private EventListener evListener; private Listener
BR> aListener; )



BR> p.s. flushSVGDocument() thanks to
BR> http://koala.ilog.fr/batik/mlists/batik-users/archives/msg03223.html


BR> //----------------------------------------------------------------------
BR> ---- // Flush SVG document
BR> //----------------------------------------------------------------------
BR> ---- public void flushSVGDocument() { Node childNode = null;
BR> SVGDocument oSVGDocument = getSVGDocument();

BR>       if (oSVGDocument != null) { SVGSVGElement s =
BR> oSVGDocument.getRootElement(); removeNodes(s); } System.gc(); }

BR> //----------------------------------------------------------------------
BR> ---- // Flush node
BR> //----------------------------------------------------------------------
BR> ---- private void removeNodes(Node n) { Node childNode = null;
BR> Node prevChildNode = null;

BR>       for (childNode = n.getLastChild(); childNode != null;) { if
BR> (childNode.hasChildNodes()) { removeNodes(childNode); }
BR> prevChildNode = childNode.getPreviousSibling(); if (!(childNode
BR> instanceof SVGOMPathElement)) { n.removeChild(childNode); }
BR> childNode = null; childNode = prevChildNode; } n = null; }




BR> ---------------------------------------------------------------------
BR> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org For
BR> additional commands, e-mail: batik-users-help@xml.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org