JDK-8197544 : Memory Leak when using Nashorn, missing gc roots
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2018-02-09
  • Updated: 2018-02-12
  • Resolved: 2018-02-12
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

A DESCRIPTION OF THE PROBLEM :
There is a memory leak in nashorn which will cause gc slowdown and OutOfMemoryErrors, but heap dumps will not report relevant gc roots.

In production this means applications will run out of memory even though they use the right algorithms and the heap dump won't really help the developer to figure out whats going on.

This is already reported as fixed in openjdk 11. Since this looks like a severe issue could that fix please be backported to a released version ?
https://bugs.openjdk.java.net/browse/JDK-8173594
OpenJDK mailing list; last year
http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2017-February/002632.html

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run Attached code using -Xmx2g 

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected:
No OutOfMemoryError gets thrown.
Expected otherwise: If an Out of memory Error does occur, the heap dump should have information on what objects are leaking from which root.
Actual: 
if you run the code using 2Gb of Heap you will get an OOME.
If you use 4gb of Heap you will have 2 LeakImpl Objects, which have no reported path to a valid gc root, yet the gc will refuse to collect these objects
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at frei.demo.LeakDemo$LeakImpl.<init>(LeakDemo.java:52)
	at frei.demo.LeakDemo.simulateLoad(LeakDemo.java:27)
	at frei.demo.LeakDemo.main(LeakDemo.java:19)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;

import javax.script.CompiledScript;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import java.util.function.Function;


public final class LeakDemo {

    private static NashornScriptEngine ENGINE = getNashornScriptEngine();
    private static CompiledScript SCRIPT;

    public static void main(String[] args) throws Exception {
        simulateLoad();
        simulateLoad();
        System.gc();
        Thread.sleep(1000000);

    }

    private static void simulateLoad() throws ScriptException {
        final CompiledScript compiledScript = getCompiledScript(ENGINE);
        compiledScript.eval(new SimplestBindings(new LeakImpl()));
    }

    private static NashornScriptEngine getNashornScriptEngine() {
        final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        final NashornScriptEngine scriptEngine = (NashornScriptEngine) factory.getScriptEngine();
        return scriptEngine;
    }



    private static CompiledScript getCompiledScript(final NashornScriptEngine scriptEngine) throws ScriptException {
        if (SCRIPT == null) {
            SCRIPT = scriptEngine.compile(" var pivot = getItem(\"pivot\");");
        }
        return SCRIPT;
    }

    public interface Leak {

        LiveItem getItem(String id);
    }


    public static final class LeakImpl implements Leak {
        private final byte[] payload = new byte[1024 * 1024 * 1024];


        @Override
        public LiveItem getItem(final String id) {
            return new LiveItem() {
            };
        }


    }

    public interface LiveItem {
    }

    public static final class SimplestBindings extends SimpleBindings {
        public SimplestBindings(Leak leak) {

            put("getItem",(Function< String, LiveItem>) leak::getItem);
        }
    }
} 
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
aggressively null out as much as you can and hope for the best.



Comments
This issue is duplicate of JDK-8081323 (JDK-8173594) which is already fixed in 10. This report is an request for backporting the original issue on 8u release. Closing as duplicate of JDK-8081323 and backport request created for JDK-8081323
12-02-2018