Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8199303

Nashorn provides a memory leaks when using Tomcat and spark-java

XMLWordPrintable

    • x86_64
    • os_x

      FULL PRODUCT VERSION :
      java version "1.8.0_144"
      Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
      Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux 2.6.32-042stab117.16
      OS X 10.13.3

      A DESCRIPTION OF THE PROBLEM :
      When I configure spark-java application from JavaScript and run this code from Tomcat, it provides the memory leak (WebappClassloader was leaked).

      The situation is very strange.
      When I add only API GET endpoint, then no leaks. WebappClassloader correctly unload.
      When I add before or after spark filter, then WebappClassloader leaked.

      I have prepared the simple code for demonstration https://bitbucket.org/lavelas/nashorn-memory-leak.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Pull source from https://bitbucket.org/lavelas/nashorn-memory-leak
      2. Create war file by command mvn package
      3. Start Tomcat
      4. Deploy war from step 2
      5. Undeploy war from step 2
      6. Repeat steps 5-4 few times
      7. Check memory leak report (for example in default Tomcat manager)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No memory leaks
      ACTUAL -
      The WebappClassloader was leaked

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import spark.servlet.SparkApplication;

      import javax.script.*;

      /**
       * Spark filter with demonstration memory leak in Nashorn
       */
      public class NashornSpark implements SparkApplication {

          public void init() {
              ScriptEngineManager sem = new ScriptEngineManager();
              ScriptEngine nashorn = sem.getEngineByName("nashorn");

              try {
                  nashorn.eval(
                          "var spark = {};\n" +
                          "spark.before = Packages.spark.Spark.before;\n" +
                          "spark.get = Packages.spark.Spark.get;\n" +
                          "spark.before('/*', function (request, response) { print('before') });\n" + // <------ Comment this line FIX memory leak!!!
                          "spark.get('/*', function (request, response) { return 'Hello spark!' });" +
                          ""
                  );
              } catch (ScriptException e) {
                  e.printStackTrace();
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Restart Tomcat

            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: