当前位置: 首页 > 知识库问答 >
问题:

Nashorn ScriptEngine 使用多少内存?

蔚桐
2023-03-14

我们目前正在为我们的一个产品添加服务器端脚本功能。作为其中的一部分,我正在评估JSR 223脚本引擎。因为我们可能会在服务器上运行大量的脚本,所以我特别担心这些脚本引擎的内存使用情况。将Rhino(苹果JDK 1.6.0_65-b14-462-11M4609,苹果OS X 10.9.2)与Nashorn(甲骨文JDK 1.8.0-b132)进行比较,每个ScriptEngine实例的内存使用量似乎有显著差异。

为了测试这一点,我使用了一个简单的程序,它触发10个空白的ScriptEngine实例,然后阻止从stdin中读取。然后我使用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 中分析这些堆转储,然后我得到以下每个实例保留的堆大小:

    < li>Rhino: 13,472字节/实例(如果我不将读取器/写入器字段设为空,则达到73,832字节/实例) < li>Nashorn: 324,408字节/实例

对于 Nashorn 来说,这 24 倍的尺寸增加是预期的吗?对于我们将要执行的脚本(主要是 I/O 绑定),执行速度不是主要关注的问题,所以我正在考虑发布我们自己的 Rhino 副本以在 Java 8 中使用。

共有1个答案

东方谦
2023-03-14

什么是纳肖恩?

Nashorn是Java8发布的JVM的JavaScript引擎。Nashorn包括一个嵌入式JavaScript解释器和一个命令行工具。Nashorn的目标是在本机JVMJava实现高性能JavaScript运行时。使用Nashorn,开发人员可以将JavaScript嵌入Java应用程序中,还可以从JavaScript代码中调用Java方法和类,从而在两种语言之间提供无缝集成。

为什么内存消耗高?

Nashorn 对象和属性映射当前无法缩放到许多属性。使 PropertyMap 不可变的原因是允许通过比较 PropertyMap 引用来快速验证内联调用站点。这将导致 Nashorn 中的高内存消耗。

一种解决方案将是切换到pre-cript-java-函数,因为在java服务器中,它将具有特定任务的java函数,并且从Nashorn引擎,您将调用该函数,它不会创建对象映射,它只会在java中执行该函数并为您提供结果,因此内存消耗相对较低,而不是使用JS函数在Java中映射所有内容。这些类型的pre-脚本-java-函数用于WSO2身份服务器自适应脚本功能。这是在Nashorn中处理高内存分配和内存消耗的一种方式。

 类似资料:
  • 问题内容: 在Java中,如果我创建一个并将N个元素放入其中,它将占用多少内存?如果依赖于实现,那么什么才是好的“猜测”? 问题答案: 编辑; 噢,天哪,我是个白痴,我提供了HashMap的信息,而不是HashTable的信息。 但是,检查后,出于内存目的,实现是相同的。 这取决于您的VM的内部内存设置(项目的包装,32位或64位指针以及字对齐/大小),并且不是由Java指定的。 可以在这里找到有

  • 问题内容: 我需要存储大量的日期(可能足够大,以至于需要考虑使用的堆空间量,因此请不要讲授过早的优化),我想知道使用某种原始表示是否有意义java.util.Date(或其他一些现有的Date类)的形式。我知道我可以进行一些性能分析来尝试一下,但是有人知道一个Date对象使用多少字节的内存吗? 问题答案: 我的直觉反应是Date的内存开销非常小。检查源代码,似乎该类仅包含一个实例字段(长为毫秒)。

  • 问题内容: 如问题所述,在Java编程语言中,有多少内存用于引用对象? 请,如果您有可信赖的来源更好。 非常感谢! 问题答案: 语言或JVM规范未指定。但是,通常公认的是,任何明智的实现在32位计算机上都是4字节,而在64位计算机上则是4到8字节(取决于压缩指针设置等)。

  • 我最近读了很多关于字符串内存分配的文章,但找不到任何细节,如果在Java8中情况相同的话。 在Java8中,像这样的字符串会使用多少内存空间?我使用64位版本。

  • 问题内容: 有没有办法找出我的Java线程在虚拟机中占用多少内存? 例如,使用堆栈跟踪转储或其他某种方式。 问题答案: Java线程将堆用作共享内存。各个线程都有其堆栈(您可以通过-Xss命令行选项设置其大小,默认为512KB),但是所有其他内存(堆)都不属于特定线程,并询问一个特定线程仅使用了多少内存没有道理。

  • 问题内容: 例如,如果我有一个带有两种情况的枚举,它是否比布尔值占用更多的内存?语言:Java,C ++ 问题答案: 在Java中,an 是成熟的类: Java编程语言的枚举类型比其他语言的枚举类型更强大。枚举声明定义了一个类(称为枚举类型)。枚举类主体可以包括方法和其他字段。 为了查看每个文件的实际大小,让我们做一个实际的文件并检查它创建的文件的内容。 假设我们有以下枚举类: 编译以上内容并反汇