Open Tomas-Kraus opened 11 years ago
@glassfishrobot Commented Reported by mryan
@glassfishrobot Commented peddapola said: instead caching Unmarshaller, just cache JAXBContext
below code should work fine, without much performance impact:
import java.io.StringReader; import java.util.List; import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement;
public class JaxbLeakTest { public static void main(String args[]) throws Exception { JAXBContext context = JAXBContext.newInstance(JaxbLeakTest.Foo.class); for (int i = 0; i < 1000; i++) { Unmarshaller unmarshaller = context.createUnmarshaller();
if (i % 100 == 0)
{ Runtime.getRuntime().gc(); System.out.println("Foo.getInstanceCount()=" + Foo.getInstanceCount()); }
try
{ unmarshaller.unmarshal(new StringReader("
catch (Exception e) { } } }
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "foo")
public static class Foo {
private List
private static AtomicInteger instanceCount = new AtomicInteger();
public Foo()
{ instanceCount.incrementAndGet(); }
protected void finalize()
{ instanceCount.decrementAndGet(); }
public static int getInstanceCount()
{ return instanceCount.get(); }
} }
@glassfishrobot Commented File: JaxbLeakTest.java Attached By: mryan
@glassfishrobot Commented Was assigned to yaroska
@glassfishrobot Commented This issue was imported from java.net JIRA JAXB-932
I have found that certain UnmarshalExceptions result in memory leaks. A reference to the unmarshalled object is held by com.sun.xml.bind.v2.runtime.unmarshaller.Scope and is never released for the lifetime of the application, which eventually results in an OutOfMemoryError if a sufficient number of UnmarshalExceptions occur.
Stacktrace of such an exception that results in a leak:
Reduced test case:
The output of the above test case, using JAXB RI 2.2.6:
In the process of creating the above test case, I found that the type of the variable "bar" has an effect on whether the leak occurs. The leak only seems to occur when bar is a List.
Reference chain from Eclipse:
Affected Versions
[2.1.10, 2.2.6]