使用第 2 代仅收集大对象堆对象有什么优势?
我知道分代垃圾收集可以提高性能,因为
- 任何对象在非 Gen2 收集中最多只能移动两次,而 Gen2 收集很少见。
- 如果系统正在执行 Gen0 收集,并且自上次 Gen0 收集以来尚未写入对象(Gen1 或 Gen2),则系统不必扫描该对象来标记其中的任何引用(因为它们都是 Gen1)或第二代)。同样,如果系统正在执行 Gen1 收集,它可以忽略自上次 Gen1 收集以来未写入的任何对象。由于垃圾收集的大部分工作是扫描对象,因此减少扫描时间是一个巨大的胜利。
不过,我很好奇,从 Gen1 垃圾收集中忽略大型对象可能会有什么性能优势?即使垃圾收集器扫描大对象,也不会重新定位它们,并且我预计 Gen1 收集仍然必须扫描其内容,除非或直到发生两个连续的 Gen1 收集而无需干预对象写入。
是否有一些我没有看到的性能优势?
I understand that generational garbage collection improves performance, since
- Any object will have to be moved at most twice in non-Gen2 collections, and Gen2 collections are rare.
- If the system is performing a Gen0 collection and an object (Gen1 or Gen2) hasn't been written since the last Gen0 collection, the system won't have to scan that object to tag any references therein (since they'll all be Gen1 or Gen2). Likewise if the system is performing a Gen1 collection, it can ignore any object not written since the last Gen1 collection. Since most of the work of garbage-collection is scanning objects, reducing the scanning time is a big win.
I'm curious, though, what performance advantage there could be to omitting large objects from Gen1 garbage collection? Large objects aren't relocated even when they're scanned by the garbage collector, and I would expect that Gen1 collections will still have to scan their contents unless or until two consecutive Gen1 collections occur without intervening object writes.
Is there some performance advantage I'm not seeing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有两件事 -
首先,大对象(大到足以位于 LOH 上)往往有更长的生命周期。短命的大型对象很少见,在需要的情况下,您通常可以重用它们。通过不扫描,您可以有效地避免扫描,而扫描几乎总是会导致保留对象。这往往会给你带来性能上的胜利。
此外,为了有效地处理 Gen1 中的对象,并获得 Gen1 提供的许多优势,它们需要能够压缩。分代收集器的一大优点是您可以压缩最新的分配,这往往有助于降低内存压力,因为碎片往往会表现得更好。 Gen1 中的大型对象会导致性能或内存问题,因为它们要么需要压缩(目前,大型对象没有被压缩,因为“移动”它们的成本很高),要么会导致额外的碎片蔓延。
There are two things -
First, large objects (large enough to be on the LOH) tend to have longer lifetimes. Short-lived large objects are rare, and in the cases where that's needed, you can typically reuse them. By not scanning, you're effectively avoiding scans that, nearly always, will result in keeping the objects anyways. This tends to give you a win in perf.
Also, in order to effectively treat objects in Gen1, and get many of the advantages provided by having a Gen1, they'd need to be able to compact. A large advantage of the generational collector is you're compacting the newest allocations, which tends to help keep the memory pressure lower as fragmentation tends to be better behaved. Large objects in Gen1 would cause performance or memory issues, as they'd either require compacting (right now, large objects are not compacted, since it's expensive to "move" them) or they'd cause extra fragmentation to creep up.