0

我正在尝试配置一个轻量级的全功能 JavaScript 引擎,以便我可以同时拥有数万个独立的上下文。每个上下文所做的事情很少(主要是事件处理、轻字符串操作、自定义计时器等),并且不需要太多堆存储,但需要独立于其他上下文。使用 Duktape,如果我在 x64 中分配 20,000 个上下文,在进行大量处理之前我会使用超过 1.6GB 的内存,或者每个大约 80KB。作为另一个数据点,如果我使用 SpiderMonkey 1.7.0,20,000 运行我大约 1.4GB 或大约 70KB ......几乎相同。我已经使用了 Duktape 必须提供的一些优化,但它似乎不会影响这种用法。

所以问题是,有没有办法将每个上下文的内存利用率降低到每个上下文的 4KB(或更少)范围?

注意:是的,我知道 SpiderMonkey 1.7.0 并不是真正的全功能,但它是为了我正在尝试做的事情,并且没有我不想要也不需要的 JIT 复杂性来自后来的引擎、V8 等。因此,将 Duktape 视为替代方案。

谢谢!

4

2 回答 2

1

新全局环境的最低启动成本几乎完全由内置对象及其属性引起:大约有 70 个内置对象,具有 250 个函数属性和 90 个值属性。您可以通过删除不必要的内置和/或内置属性来减少这种情况。

您可以做的一件事是启用 DUK_OPT_LIGHTFUNC_BUILTINS,它将大多数内置函数替换为更轻量级的函数表示,从而减少内置对象数。这有一些副作用,例如内置函数的自动生成的“名称”属性可读性较差。

如果您的上下文很小,您可以做的另一件事是使用“指针压缩”,这会导致 Duktape 用 16 位值表示堆指针。您需要提供宏来编码/解码指向/来自此表示的指针。这种方法仅适用于单个 Duktape 堆的最大大小为 ~256kB(假设 align-by-4 分配)。该功能是为嵌入式低内存 32 位平台开发的,因此它可能无法在 64 位环境中理想地工作(master 分支有一些针对指针压缩和 64 位平台的修复,所以如果你尝试这个,请使用 master)。

使用任何这些措施都不可能达到 4 kB/上下文 - 有太多的内置对象和属性为此。只有当您为多个脚本共享全局对象时,才能达到每个上下文的内存量,这可能会也可能不会,具体取决于脚本的隔离和线程需求。

于 2015-07-21T15:44:22.697 回答
1

作为这个问题的快速更新:Duktape 1.5.0 将有一个配置选项来将内置字符串和对象放入 ROM(只读数据部分):https ://github.com/svaarala/duktape/pull/559 。相同的只读字符串和对象将在所有 Duktape 堆和上下文之间共享,而无需使用任何 RAM。一旦该功能最终确定,还可以将您自己的字符串和内置函数放入只读数据部分,这样它们就不会在每个堆/上下文中消耗任何 RAM。

通过此更改,可以在 32 位目标上达到约 4 kB 的启动 RAM 使用量,在 64 位目标上达到约 8 kB。

于 2016-01-30T12:14:07.057 回答