防止 Java Nashorn 在动态创建地图时过度占用内存
Preventing Java Nashorn from super excessive memory usage when dynamically creating a map
这段微不足道的代码,当 运行 Nashorn 时,会导致完整的 GC
var x = {};
for (var i = 0; i < 10000; i++) {
var key = "key-" + i;
x[key] = i;
}
通读 Nashorn 实现,我相信每次添加对象(使用 PropertyMap class)都会克隆一个对象,添加新键,将其链接到先前版本的 "history" 作为弱对象参考,等等等等。
这使得上面的代码在内存和时间上都是二次的。
有什么办法可以避免吗?
您尝试过使用原型吗?
我不确定(没有与 Nashorn 合作),但也许这可以帮助你:
var x = function() {};
for (var i = 0; i < 10000; i++) {
var key = "key-" + i;
x.prototype[key] = i;
}
console.log(new x());
您的分析是正确的,Nashorn 对象和 属性 地图当前无法扩展到很多属性。使 PropertyMap 不可变的原因是允许通过比较 PropertyMap 引用来快速验证内联调用站点。
一种解决方案是在属性数量超过某个阈值时切换到每个 ScriptObject,可变 属性 映射。我们可能会在 Nashorn 的未来版本中实现这一点,但我现在不能做出任何承诺。
作为解决方法,您可以使用 Java 映射来存储大量键值对。此外,在 JDK 9 中,Nashorn 将获得一些 ECMAScript 6 功能,其中包括新的 Map、Set、WeakMap 和 WeakSet 集合。
这段微不足道的代码,当 运行 Nashorn 时,会导致完整的 GC
var x = {};
for (var i = 0; i < 10000; i++) {
var key = "key-" + i;
x[key] = i;
}
通读 Nashorn 实现,我相信每次添加对象(使用 PropertyMap class)都会克隆一个对象,添加新键,将其链接到先前版本的 "history" 作为弱对象参考,等等等等。
这使得上面的代码在内存和时间上都是二次的。
有什么办法可以避免吗?
您尝试过使用原型吗? 我不确定(没有与 Nashorn 合作),但也许这可以帮助你:
var x = function() {};
for (var i = 0; i < 10000; i++) {
var key = "key-" + i;
x.prototype[key] = i;
}
console.log(new x());
您的分析是正确的,Nashorn 对象和 属性 地图当前无法扩展到很多属性。使 PropertyMap 不可变的原因是允许通过比较 PropertyMap 引用来快速验证内联调用站点。
一种解决方案是在属性数量超过某个阈值时切换到每个 ScriptObject,可变 属性 映射。我们可能会在 Nashorn 的未来版本中实现这一点,但我现在不能做出任何承诺。
作为解决方法,您可以使用 Java 映射来存储大量键值对。此外,在 JDK 9 中,Nashorn 将获得一些 ECMAScript 6 功能,其中包括新的 Map、Set、WeakMap 和 WeakSet 集合。