垃圾收集和线程

Has*_*yed 21 java clr garbage-collection memory-management blocking

AFAIK当GC正在执行其操作时,VM会阻止所有正在运行的线程 - 或者至少在压缩堆时.这是CLR和JVM的现代实现中的情况(截至2010年1月的生产版本)?请不要提供有关GC的基本链接,因为我了解基本的工作原理.

我假设全局锁定就是这种情况,因为当压缩发生时,引用在移动期间可能是无效的,并且最简单的方法就是锁定整个堆(即,通过阻塞所有线程来间接).我可以想象更强大的机制,但KISS经常占上风.

如果我不正确,我的问题将通过对用于最小化阻塞的策略的简单解释来回答.如果我的假设是正确的,请提供以下两个问题的一些见解:

  1. 如果这确实是这种行为,那么像JBOSS和Glassfish这样的重量级企业引擎如何保持一致的高TPS率?我在JBOSS上做了一些谷歌搜索,我期待在APACHE上找到适合网络处理的内存分配器.

  2. 面对NUMA式架构(可能在不久的将来),这听起来像是一场灾难,除非进程受到线程和内存分配的CPU限制.

Ste*_*n C 16

答案是这取决于所使用的垃圾收集算法.在某些情况下,您在GC期间停止所有线程是正确的.在其他情况下,在正常线程运行时垃圾收集继续进行是不正确的.要了解GC如何实现这一目标,您需要详细了解垃圾收集器的理论和术语,并结合对特定收集器的理解.简单的解释根本不适合.

哦,是的,值得指出的是,许多现代收藏家本身没有压实阶段.相反,它们通过将活动对象复制到新的"空间"并在完成时将旧"空间"归零来工作.

如果我不正确,我的问题将通过对用于最小化阻塞的策略的简单解释来回答.

如果您真的想了解垃圾收集器的工作原理,我建议:

...并注意找到生产垃圾收集器内部的准确,详细的公开描述并不容易.(虽然在Hotspot GC的情况下,您可以查看源代码......)

编辑:回应OP的评论......

"看起来就像我想的那样 - 没有绕过"阻止世界"的一部分."

这取决于.对于Java 6 Concurrent Collector,在标记根(包括堆栈)期间有两个暂停,然后标记/复制其他对象并行进行.对于其他类型的并发收集器,在收集器运行时使用读取或写入障碍来捕获收集器和应用程序线程否则会相互干扰的情况.我现在没有这里的[琼斯]副本,但我还记得有可能使"停止世界"的时间间隔可以忽略不计......代价是更昂贵的指针操作和/或没有全部收集垃圾.

  • 据我所知,尽管大多数任务同时运行,但即使是最并发的垃圾收集器也会"停止世界"进行一些工作.但是,JVM 6中的CMS收集器确实在停止世界阶段使用所有可用的CPU. (2认同)