How much memory does a Nashorn ScriptEngine use?
Asked Answered
T

1

10

We are currently in the process of adding a server-side scripting capability to one of our products. As part of this I am evaluating JSR 223 script engines. As we may potentially be running large numbers of scripts on the server, I am particularly concerned about memory usage of these script engines. Comparing Rhino (Apple JDK 1.6.0_65-b14-462-11M4609, Mac OS X 10.9.2) with Nashorn (Oracle JDK 1.8.0-b132) there seems to be a dramatic difference in memory usage per ScriptEngine instance.

To test this, I use a simple program that fires up 10 blank ScriptEngine instances and then blocks reading from stdin. I then use jmap to take a heap dump (jmap -dump:format=b,file=heap.bin ) and then search for the relevant script engine instance in the dump:

import javax.script.*;
public class test {
    public static void main(String...args) throws Exception {
        ScriptContext context = new SimpleScriptContext();
        context.setWriter(null);
        context.setErrorWriter(null);
        context.setReader(null);
        ScriptEngine js[] = new ScriptEngine[10];
        for (int i = 0; i < 10; ++i) {
            js[i] = new ScriptEngineManager().getEngineByName("javascript");
            js[i].setContext(context);
            System.out.println(js[i].getClass().toString());
        }
        System.in.read();
    }
}

The reason for nulling out the various reader/writer fields in the context is because we do not use them, and earlier heap dumps for Rhino suggest that they constitute a significant fraction of the per-instance overhead (and do not appear to be shared).

Analysing these heap dumps in Eclipse MAT then I get the following per-instance retained heap sizes:

  • Rhino: 13,472 bytes/instance (goes up to 73,832 bytes/instance if I do not null the reader/writer fields)
  • Nashorn: 324,408 bytes/instance

Is this 24x increase in size for Nashorn to be expected? Execution speed is not a major concern for the scripts we will be executing (which will mostly be I/O bound), so I am considering shipping our own copy of Rhino for use in Java 8+.

Theophylline answered 9/6, 2014 at 8:47 Comment(2)
What did you end yo using? Could you confirm the memory overhead for Nashorn?Height
We shipped our own copy of Rhino.Theophylline
V
1

What is Nashorn?

Nashorn is a JavaScript engine for the JVM that is released with Java 8. Nashorn comprises an embedded JavaScript interpreter and a command-line tool. The objective of Nashorn is to implement a high-performance JavaScript runtime in Java with a native JVM. Using Nashorn, a developer can embed JavaScript in a Java application and can also invoke Java methods and classes from the JavaScript code providing seamless integration between the two languages.

Why high memory consumption?

Nashorn objects and property maps do not currently scale to lots of properties. The reason for making PropertyMap immutable is to allow quick validation of inline call sites by comparing PropertyMap references. This will lead to high memory consumption in Nashorn.

One solution would be to switch to pre-script-java-functions, because in java server it will have the java functions for a particular task and from Nashorn engine, you will call that function it won't create object mapping and everything it will only execute the function in java and give you the result so memory consumption is comparatively low rather than using JS functions map everything in Java. These kinds of pre-script-java-functionsare used in WSO2-Identity Server Adaptive Script functionality. This is one way of handling high memory allocation and memory consumption in Nashorn.

Volga answered 30/7, 2021 at 4:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.