OK.

I have the following document loaded in memory as a DOM:

<root>
  <a_node>
    <some_node>
       <child>
         ...
       </child>
    </some_node>
  </a_node>

  ...

</root>

and repeatedly want to clone <some_node> in order to manipulate
it, but keep the original node. Shouldn't the memory be reclaimed
in the code in my original example?

I have attached an example (as text files for your convenience)
illustrating my problem. The output is as follows:

Memory usage after 0 clones: 2204464
Memory usage after 1000 clones: 2853408
Memory usage after 2000 clones: 3501408
Memory usage after 3000 clones: 4149408
Memory usage after 4000 clones: 4797408
Memory usage after 5000 clones: 5445408
Memory usage after 6000 clones: 6093408
Memory usage after 7000 clones: 6741408
Memory usage after 8000 clones: 7389408
Memory usage after 9000 clones: 8037408
Memory usage after 10000 clones: 8685408

The forced garbage collecting does not do affect the
result noticeably. Setting the cloned node to null
does nothing.

If this is the correct behavior, how can I delete
the cloned node when I do not need it anymore?

/Christian


Andy Clark wrote:
> 
> Christian Lizell wrote:
> > Is it the correct behavior that the following statement
> > is not releasing the memory for the cloned node?
> >
> >         Node clonedNode = someNode.cloneNode(true);
> >         clonedNode = null;
> 
> Unless the cloned node is actually a child node in the
> document, the cloned node can be reclaimed. Even though
> the cloned node has a link to the document, what is
> important is the objects that have links to the cloned
> node. If noone references it, then it can be reclaimed.
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;

public class CloneTest {

    public static void main(String[] args) {
        // Parse the document
        DOMParser parser = new DOMParser();
        try {
            parser.parse("clonetest.xml");
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }

        // Get some_node
        Node someNode = null;
        try {
            someNode = 
parser.getDocument().getElementsByTagName("some_node").item(0);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
        parser = null; // Just in case

        // Make clones
        for (int i=0; i<=10000; i++) {
            Node clonedNode = someNode.cloneNode(true);
            clonedNode = null;
            if ((i%1000) == 0) {
                System.gc(); System.runFinalization();
                Runtime rt = Runtime.getRuntime();
                System.out.println("Memory usage after " + i + " clones: " + 
(rt.totalMemory()-rt.freeMemory()));
            }
        }
    }
}
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>

<root>
  <a_node>
    <some_node>
       <child>
         blah
       </child>
    </some_node>
  </a_node>
</root>

Reply via email to