在并发系统中进行垃圾收集的可能方法有哪些?
我需要为支持并发的解释器编写一个垃圾收集器,但我只能找到有关垃圾收集的信息,而与并发无关。
多线程系统中对象的垃圾回收是否有特定的方法?我在哪里可以找到有关其架构和实现的信息?
I need to write a garbage collector for an interpreter that will support concurrency, but I can only find information about garbage collection without anything to do with concurrency.
Are there specific methods for garbage collection of objects in multithreaded systems? Where can I find information on their architecture and implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
并发垃圾回收实际上要正确执行要困难得多。然而,已经有针对并发垃圾收集算法的研究。
马克&扫描:http://doc.cat-v.org/inferno/concurrent_gc/
马克&扫一扫(PDF警告):http://www.win。 tue.nl/~jfg/articles/CSR-04-31.pdf
分代复制:https://labs.oracle.com/techrep/2000/abstract-88.html
分代复制:http://chaoticjava.com/posts/parallel-and-concurrent-garbage-collectors/
困难在于同步线程,因此堆不是' t 处于不一致(无效)状态。
Concurrent garbage collection is actually a lot trickier to get right. There has been research into concurrent garbage collection algorithms, however.
Mark & Sweep: http://doc.cat-v.org/inferno/concurrent_gc/
Mark & Sweep (PDF warning): http://www.win.tue.nl/~jfg/articles/CSR-04-31.pdf
Generational-Copying: https://labs.oracle.com/techrep/2000/abstract-88.html
Generational-Copying: http://chaoticjava.com/posts/parallel-and-concurrent-garbage-collectors/
The difficulty is synchronizing the threads, so the heap isn't left in an inconsistent (invalid) state.
也许我只是不太理解这一点......但是并发性与对一个对象的存活数量有什么关系呢?它要么有活生生的参考资料,要么没有;多线程对此没有影响。
我可以看到也许必须单独追踪每个线程才能查看哪些引用是活动的或无效的。但这应该只是多次应用单线程跟踪。
另外,为什么不在已经完成所有这些工作的虚拟机上编写解释器呢?就像 JRuby (Java VM) 或 IronPython (.NET) 所做的那样。
Maybe I'm just not understanding this well... But what would concurrency have to do with how many references to an object are alive? It either has living references or it doesn't; multiple threads have no effect on that.
I could see maybe having to trace out each thread separately to see what references are alive or not. But that should be just applying the single-threaded trace multiple times.
Also, why not just program your interpreter on top of a VM that already does all this? Like JRuby (Java VM) or IronPython (.NET) have done.
有两种主要解决方案:
当值从一个线程传递到另一个线程时,通过深度复制值来禁止突变并利用生成的单向堆中的引用透明度。然后使用非并发收集。 Erlang 就是这样做的。
使用并发垃圾收集器。有关详细信息,请参阅垃圾收集手册第 15 章“并发垃圾收集”。 .NET 和 JVM 执行此操作。您需要一个写屏障(Dijkstra、Steele 或 Yuasa),以便在收集器运行时记录堆拓扑的突变。
并发垃圾收集器的范围从完全并发(无暂停)到大部分并发(一些短暂的停止世界暂停,通常是为了获得全局根的自洽快照)。完全并发在吞吐量方面的成本很高,因为让 GC 了解不断变化的堆拓扑需要细粒度的同步。使用漂亮的非常并发垃圾收集器 (VCGC) 等收集器可以实现粗粒度同步。 FWIW,我写了一篇关于 F# 中 VCGC 实现的文章< /a> 为 F#.NET 期刊。
There are two main solutions:
Prohibit mutation and exploit the referential transparency in the resulting unidirectional heap by deep copying values when they are passed from one thread to another. Then use non-concurrent collection. Erlang does this.
Use a concurrent garbage collector. See the Garbage Collection Handbook chapter 15, Concurrent Garbage Collection, for detailed information. .NET and the JVM do this. You'll need a write barrier (Dijkstra, Steele or Yuasa) in order to record mutations of the heap topology while the collector is running.
Concurrent garbage collectors range from full concurrency (no pauses) to mostly concurrent (some short stop-the-world pauses, usually to get a self-consistent snapshot of the global roots). Full concurrency is costly in terms of throughput because keeping the GC apprised of the constantly-changing heap topology requires fine-grained synchronization. Coarse-grained synchronization is possible with collectors like the beautiful Very Concurrent Garbage Collector (VCGC). FWIW, I wrote an article about a VCGC implementation in F# for the F#.NET Journal.