2013-01-16 55 views
0

我在node.js(数百万)中有一个非常大的对象集合,我需要保留在内存中用于缓存目的(它们在几个全局散列对象中维护)。每个哈希集合存储约750k个密钥。垃圾收集期间是否会检查持久性收集?

为了将GC降到最低,我想找出最佳的方法来存储这些项目。将这些项目分成数以百计的哈希值是否会更好?我应该可能不使用哈希?有没有办法让它们完全离开堆栈,所以它们从来没有被GC检查过(如果是的话,我会怎么做)?

回答

2

没有公共的API来控制JavaScript的垃圾收集。

但是多年来GC已经走过了很长一段路。现代GC的实现会注意到有些物体会长寿,并将它们放入一个特殊的“区域”,这个区域很少会被收集。

这个确切的工作原理完全依赖于实现;每个浏览器都是自己的东西,通常,当新的浏览器版本发布时,这也经常发生变化。

编辑内存和组织的布局是完全不相关的。如果没有花几个星期的时间阅读实际代码,现代GC就很难理解。所以我现在解释的是一个非常简单的图片;真正的代码将会有所不同(并且一些GC将使用完全不同的技巧来实现相同的目标)。

想象一下,GC为每个对象都有一个计数器,在这个计数器中它的数量在过去经常出现。此外,它还有几个列表,用于保存不同年龄的物体,也就是说,物体的计数器已经通过了一定的阈值。所以当计数器达到一定的限制时,对象将移动到下一个列表中。

每次GC运行时都会访问第一个列表。第二个列表仅适用于每第N次GC运行。

另一种实现可能会将新对象添加到“GC列表”的顶部,并且对于每个GC运行,它只会检查N个元素。很长一段时间,活的物体会在列表中移动,过了一段时间后,它们不会每次都被检查。

这对你意味着什么,你不必做任何事情; GC会发现你的巨大地图存在很长时间(对于地图中的所有对象也是如此),过了一段时间,它将开始忽略这个数据结构。

+0

我实际上特别感兴趣的是如何在node.js中实现,但我认为它使用v8以来一样。当你说很少收集,那是什么构成的?例如,如果我有一个具有10,000,000个键的散列,如果它可以告诉散列不应该是GC'd,它是否仍然会关闭并检查散列中的每个单独的键?如果它会检查每个密钥,是不是每个包含100个散列的散列都有100个散列会更好?有关系吗?试图找出如何避免在这个集合上的GC。 – AlexGad

+1

我在node.js组https://groups.google.com/forum/?fromgroups=#!topic/nodejs/BO6JdYi4n2k中发现了一个有趣的讨论。看来,V8不会对大对象进行分割扫描,因此它会遍历整个对象。如果我将我的物体分解成许多较小的物体,那么将发生分割扫描,使GC不会突然停止所有物体走过一百万个物体。有人评论说,最好把它放在堆外面。这将如何完成?通过外部c代码? – AlexGad

+0

@AlexGad:当然,但下一个版本的v8可能会完全不同。问题:您的目标是[过早优化](http://c2.com/cgi/wiki?PrematureOptimization)还是您确实存在需要解决的问题? –