我有一个对象
{}
,它包含很多子对象,它基本上就像一个大型的嵌入式对象键值存储。出于性能原因,它们需要位于内存中(对它们的访问延迟至关重要)。
该对象在启动时加载一次并保持静态。 我认为该应用程序在主要 GC 阶段有很大的 GC 滞后,因为它还需要遍历这个巨大的引用树。 然而,我知道这是静态的,我想以某种方式将其从 GC 中排除。
也许一些v8 gc专家还可以推荐如何跟踪这个对象是否确实被major GC扫描?或者如果无法消除如何加快此扫描速度?
我尝试使用晦涩的“永恒”句柄(原生插件),使父对象成为永恒,希望GC算法可以避免扫描这棵巨大的树,但虽然它确实变得永恒,但似乎标记清除并没有获得任何速度(或者我无法在较小的测试中看到差异)。 我确实确保该对象成为永恒的,并且我确实确保这可以防止它(以及所有子对象)被收集,但也许不会被扫描。
还有其他高级技巧可以用来从 GC 中“隐藏”这个对象吗?
我想另一个想法是将此对象序列化到某种外部存储器(缓冲区?)并在访问时反序列化,但正如我所说,我担心访问的延迟损失会太大。
GC 必须访问所有活动对象来标记它们,没有办法解决这个问题。
对于数字数据,您可以使用 TypedArray(或缓冲区),因为 GC 不会访问它们的内容(因为那里没有指针)。不过,听起来您需要存储对象,在这种情况下,我同意按需反序列化可能会产生太多开销的担忧。
由于主要 GC 周期是增量且部分并发的,因此出现长时间暂停的情况并不常见。我怀疑这些暂停的实际原因与您的大型对象树没有直接关系。也许性能概况可以让我们了解正在发生的事情。