I am trying to find a workaround for the JDK Nashorn bug JDK-8229011.
I reproduced the error with the script linked in the bug ticket and took several heap dumps. I used JProfiler and Eclipse Memory Analyzer to find the root of the problem. But, I always end up in unreachable paths and I don't understand why the objects are not garbage collected. AFAIS there are no finalizers to keep them alive. If I open the heap dump in JProfiler without disabling "Full GC on Dump", JProfiler will even throw the unreachable objects away. But the GC itself won't. I tested with G1 GC, but its the same with CMS.
You can get a sample dump in 1-2 minutes with any JDK > 8 by running the following script with the settings: -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
public class TestJsMemLeak
{
public static final class JsJavaUtil
{
private long counter = 0;
public long testFunc()
{
return counter++;
}
}
public static void main(final String[] args) throws Exception
{
System.setProperty("nashorn.args", "--no-java -doe -ot=false --language=es6 --no-deprecation-warning --lazy-compilation=false");
for (long i = 0; true; ++i)
{
final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
scriptEngine.put("JsJavaUtil", new JsJavaUtil());
scriptEngine.eval("for (var i = 0; i < 10; ++i) {\n" + " JsJavaUtil.testFunc();\n" + "}");
System.gc();
if (i % 100 == 0)
{
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
}
}
}
}
Running this will lead to a dump with an about 6-7 MB of unreachable java.lang.ClassValue$ClassValueMap
I am looking for some hints, what is keeping these objects alive.
I don't know what is going on, but the latest development build of Eclipse Memory Analyzer gives some interesting findings. Snapshot comparison - load heap dump 1, load heap dump 2, run "Leak Suspects by Snapshot Comparison : includes leak suspects and a system overview from comparing two snapshots."
Also Component report says:
Details »