垃圾回收必须访问所有存在的对象,以便找到可以回收的内存。(有很多世代只是延迟了一下)
在所有条件都相同的情况下,最好先访问已分页到RAM中的对象,然后再分页其他块并分页出某些对象。
另一种可能是,当OS希望从进程中删除一整页的内存时,首先会询问GC是否具有可以放弃而无需分页的页面。GC通常可以通过从页面移动对象来完成,因此可以在OS需要页面的限期内清除该页面。
但是,我想不起任何与OS分页系统集成的垃圾收集器,这些垃圾收集器会驱动GC的工作顺序。
垃圾回收必须访问所有存在的对象,以便找到可以回收的内存。(有很多世代只是延迟了一下)
在所有条件都相同的情况下,最好先访问已分页到RAM中的对象,然后再分页其他块并分页出某些对象。
另一种可能是,当OS希望从进程中删除一整页的内存时,首先会询问GC是否具有可以放弃而无需分页的页面。GC通常可以通过从页面移动对象来完成,因此可以在OS需要页面的限期内清除该页面。
但是,我想不起任何与OS分页系统集成的垃圾收集器,这些垃圾收集器会驱动GC的工作顺序。
Answers:
我记得,复制收集器应该是分页友好的,因为通过复制进行跟踪会改善指针引用的局部性。这对程序(变量器)有积极的影响,在跟踪链接时将减少较少的页面错误,并且由于跟踪也将减少较少的页面错误,因此还将改善下一个收集周期。跟踪议程(应该先处理指针)可能会影响改善数据局部性的有效性。这可以通过测量关于在不同类型的单元中对不同指针的访问次数的统计来改善。
现在,如果您通常考虑使用跟踪收集器,则通常必须维护一个结构来跟踪尚未跟踪的指针。可能有可能组织此结构,以便将指向同一页面的所有等待指针保持在一起(尽管在某些情况下,这可能会占用更多空间,具体取决于保留此类指针列表的可用技术)。然后一种可能的策略是,当内存中没有等待的指针时,总是先跟踪指向同一页面的最大等待指针集。
关于在我回答之后添加的第三段中的问题,副本收集还是一个答案。由于页面已完全释放,因此操作系统可以在收集时减少分配的物理页面的数量。使用标记和清除收集器,整页无蜂的事件可能会少得多,因此不值得考虑特定的机制。
这种想法很自然,并且可能在某些论文中有所描述。但是我不记得它是如何使用的。我认为有关Lisp GC的早期论文包含其中一些想法(例如:应首先遵循car还是cdr?)。
在副本收集这一角色中的好消息还在于,分页对副本收集很友好,因为它增加了可用的存储空间。回想一下,复制收集器原则上需要的空间是实际数据存储空间的两倍。现在,分页的效果还取决于计算机的地址空间以及可用的物理内存。在较旧的计算机中,物理内存远远小于可用的地址空间,因此分页实际上是一种空间奖励,从而允许使用诸如复制GC之类的策略。即使物理空间与地址空间一样大,也可能要共享它,以便使用GC的进程在不进行分页的情况下也将具有较少的地址空间(请参阅分页))。这些说法由于使用了世代收集器而显得有些多余。由于这些特质,并且因为年轻一代大多是短命的,所以他们通常将拷贝收集用于年轻一代。
然后,您拥有了世代GC与缓存系统的所有交互,在上一个问题中已经进行了讨论:世代垃圾收集器固有地对缓存友好吗?
有关这些问题的更多信息,我将使用关键字垃圾收集和本地性等在网络上搜索。
Emery Berger,Matthew Hertz和Yi Feng在此方面做了一些工作。
垃圾回收具有许多软件工程优势,但是与虚拟内存管理器的交互很差。现有的垃圾收集器需要的页面比应用程序的工作集和触摸页面要多得多,而与内存中的页面无关,尤其是在全堆垃圾收集期间。产生的页面调度会导致吞吐量骤降,暂停时间会激增至几秒甚至几分钟。
我提出了一个避免分页的垃圾收集器。该书签收集器与虚拟内存管理器协作以指导其驱逐决策。
这是埃默里(Emery)的演讲视频,他写了一篇论文《无分页的垃圾收集》
由于某些原因,以后似乎没有太多工作要做,也没有任何“现实世界”的用法。在文章的最后,它说:“我们正在开发书签收集算法的并发变体”,但我无法对其进行追踪。
CRAMM:对垃圾收集应用程序的虚拟内存支持着眼于更改操作系统以使GC创建更少的分页。
我们引入了一个主要是复制集合的扩展,该扩展使用页面驻留来确定何时重新定位对象。我们的收藏家会提升具有较高驻留率的页面,从而避免不必要的工作和浪费的空间。它可以预测每个页面的驻留时间,但是当其预测不准确时,我们的收集器可以通过使用它来满足分配请求来回收未占用的空间。使用驻留性可以使我们的收集器动态地平衡复制和非复制收集的权衡。我们的技术比纯复制收集器需要更少的空间,并支持对象固定,而不会牺牲对象的重定位能力。与其他混合方法不同,我们的收集器不依赖于特定于应用程序的配置,并且可以快速响应变化的应用程序行为。我们的测量结果表明,我们的混合动力车在各种条件下均表现良好;当堆空间足够大时,它更喜欢复制收集,但是当空间有限时,它会选择不复制。