Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is no "memory leak" in this case. Memory leak are defined as instances where an application cannot reclaim memory. In this case there is no leak, as all <code>XObject</code> (and <code>XObject[]</code>) instances can be reclaimed at some point in time.</p> <p>A memory profiler snapshot obtained from VisualVM yields the following observations:</p> <ul> <li>All <code>XObject</code> (and <code>XObject[]</code>) instances are created when the <code>XPathExpression.evaluate</code> method is invoked.</li> <li><code>XObject</code> instances are reclaimed when they are no longer reachable from a GC root. In your case, the GC roots are the <code>result</code> and <code>testResult</code> local variables which are local to the stack of the main thread.</li> </ul> <p>Based on the above, I suppose that your application is experiencing or likely to experience a memory exhaustion as opposed to a memory leak. This is true when you have a large number of <code>XObject</code>/<code>XObject[]</code> instances from an XPath expression evaluation, that haven't been reclaimed by the garbage collector because </p> <ul> <li>they are either still reachable from a GC root,</li> <li>or the garbage collector hasn't come around to reclaiming them yet.</li> </ul> <p>The only solution to the first is to retain objects around in memory for the duration that they are required. You do not seem to be violating that in your code, but your code could certainly be made more efficient - you are retaining the result of the first XPath expression, to be used by the second, when certainly it could be performed more efficiently. <code>//Product/Test</code> can be used to retrieve the <code>Test</code> nodes, and also obtain the parent <code>Product</code> Nodes' id values are shown in the following snippet (which evaluates only one XPath expression instead of two):</p> <pre><code>expr = xpath.compile("//Product/Test"); nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); for (int i = 0; i &lt; nodes.getLength(); i++) { Node node = nodes.item(i); System.out.println(node.getParentNode().getAttributes().getNamedItem("id")); System.out.println(node.getTextContent()); } System.out.println(nodes.getLength()); </code></pre> <p>As far as the second observation is concerned, you ought to obtain GC logs (using the <code>verbose:gc</code> JVM startup flag). You could then decide to resize the young generation, if you have too many shortlived objects being created, as there is the possible likelihood that reachable objects will be moved to the tenured generation resulting in the likelihood that a major collection will be required to reclaim objects that are actually shortlived by nature. In an ideal scenario (considering your posted code), a young gen collection cycle should be done every few iterations of the for loop, as the <code>XObject</code> instances that are local to the loop, should be reclaimed as soon as the block's local variables go out of scope.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload