Сколько памяти использует Nashorn ScriptEngine?
В настоящее время мы добавляем возможность написания сценариев на стороне сервера к одному из наших продуктов. В рамках этого я оцениваю скриптовые движки JSR 223. Поскольку мы потенциально можем запускать большое количество сценариев на сервере, меня особенно беспокоит использование памяти этими механизмами сценариев. Сравнивая Rhino (Apple JDK 1.6.0_65-b14-462-11M4609, Mac OS X 10.9.2) с Nashorn (Oracle JDK 1.8.0-b132), выявляется существенная разница в использовании памяти на экземпляр ScriptEngine.
Чтобы проверить это, я использую простую программу, которая запускает 10 пустых экземпляров ScriptEngine, а затем блокирует чтение из стандартного ввода. Затем я использую jmap, чтобы получить дамп кучи (jmap -dump:format=b,file=heap.bin), а затем ищу соответствующий экземпляр обработчика сценариев в дампе:
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();
}
}
Причина обнуления различных полей чтения / записи в контексте заключается в том, что мы не используем их, и более ранние дампы кучи для Rhino предполагают, что они составляют значительную долю накладных расходов на экземпляр (и, по-видимому, не используются совместно).,
Анализируя эти дампы кучи в Eclipse MAT, я получаю следующие размеры кучи для каждого экземпляра:
- Rhino: 13 472 байт / экземпляр (до 73 832 байт / экземпляр, если я не обнуляю поля чтения / записи)
- Нашорн: 324 408 байт / экземпляр
Ожидается ли увеличение Nashorn в 24 раза? Скорость выполнения не является основной проблемой для сценариев, которые мы будем выполнять (которые в основном будут связаны с вводом / выводом), поэтому я рассматриваю возможность отправки нашей собственной копии Rhino для использования в Java 8+.
2 ответа
Что такое Нашорн?
Nashorn - это движок JavaScript для JVM, выпущенный вместе с Java 8. Nashorn включает встроенный интерпретатор JavaScript и инструмент командной строки. Задача Nashorn - реализовать высокопроизводительную среду выполнения JavaScript на Java с собственной JVM. Используя Nashorn, разработчик может встраивать JavaScript в приложение Java, а также вызывать методы и классы Java из кода JavaScript, обеспечивая бесшовную интеграцию между двумя языками.
Почему большое потребление памяти?
Объекты Nashorn и карты свойств в настоящее время не масштабируются для многих свойств. Причина для того, чтобы сделать PropertyMap неизменяемым, состоит в том, чтобы позволить быструю проверку сайтов встроенных вызовов путем сравнения ссылок PropertyMap. Это приведет к высокому потреблению памяти в Nashorn.
Одним из решений было бы переключиться на предварительные сценарии-java-функции, потому что на java-сервере он будет иметь java-функции для конкретной задачи, а из движка Nashorn вы вызовете эту функцию, она не будет создавать сопоставление объектов и все, что будет выполняйте функцию только в java и дайте вам результат, поэтому потребление памяти сравнительно низкое, а не использование функций JS, отображающих все в Java. Эти виды предварительных сценариев java-функций используются в функциональности адаптивного сценария WSO2-Identity Server. Это один из способов справиться с высоким распределением и потреблением памяти в Nashorn.
https://seniorjava.wordpress.com/ Может быть, эта ссылка может помочь. Не уверен, что вы все еще работаете над этим.