JDK-8132113 : Memory leak in Nashorn when accessing arguments object inside function()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u40,8u51,8u60,9
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2015-07-22
  • Updated: 2015-07-22
  • Resolved: 2015-07-22
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Darwin local 13.4.0 Darwin Kernel Version 13.4.0: Sun Aug 17 19:50:11 PDT 2014; root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64

A DESCRIPTION OF THE PROBLEM :
When accessing the 'arguments' javascript object inside a javascript function() being executed in Nashorn, a memory leak occurs, from what I can tell it means that a bunch of nashorn generated classes never get GCd.

It is easily reproduced, but importantly the JS function that is accessing the arguments object needs to be eval'd into the script engine context in a separate eval() call for it to leak. If the function and caller of the function are eval'd at the same time it does not occur.

REGRESSION.  Last worked in version 8u25

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run provided test
2. See System.Out logging with the number of classes loaded every 1000 JS evals
3. Eventually get an OOME

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Nashorn generated classes are GCd properly, with the number of loaded classes not trending up significantly over time.
ACTUAL -
Nashorn generated classes are not GCd properly, the number of loaded classes trends up significantly over time (seconds), eventually leading to an OOME.

REPRODUCIBILITY :
This bug can be reproduced always.

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

import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.util.Random;

public class MemoryLeakTest {

    public static void main(String[] args) throws ScriptException {
        ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
        ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
        for (int x=0; x<1000000;x ++){
            //function has to be evald in a different call than actually executing the function, otherwise problem doesn't occur
            engine.eval("Wrapper = { smth: function() { return arguments.length } }");
            //eval script with a random number to avoid hitting the compilation cache
            engine.eval("var blah = " + new Random().nextInt(100000) + " ; Wrapper.smth('/test', function() {})");

            if(x % 1000 == 0){
                System.out.println("Number of classes loaded: " + classLoadingMXBean.getLoadedClassCount());
            }

        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use update 25


Comments
This is a duplicate of JDK-8131340. I verified the bug is no longer reproducible with the fix for that bug.
22-07-2015