且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

垃圾收集和线程

更新时间:2022-11-09 10:02:10

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



哦,是的,值得指出的是,许多现代收藏家本身没有压缩阶段。相反,他们通过将活动对象复制到新的空间并在完成时将旧的空间调零。


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


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



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



编辑:回应OP评论...


看起来就像我想的那样 - 没有避开停止世界的部分。

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


AFAIK when a GC is doing its thing the VM blocks all running threads -- or at least when it is compacting the heap. Is this the case in modern implementions of the CLR and the JVM (Production versions as of January 2010) ? Please do not provide basic links on GC as I understand the rudimentary workings.

I assume global locking is the case as when compaction occurs references might be invalid during the move period, and it seems simplest just to lock the entire heap (i.e., indirectly by blocking all threads). I can imagine more robust mechanisms, but KISS often prevails.

If I am incorrect my question would be answered by a simple explanation of the strategy used to minimise blocking. If my assumption is correct please provide some insight on the following two questions:

  1. If this is indeed the behaviour, how do heavyweight enterprise engines like JBOSS and Glassfish maintain a consistantly high TPS rate ? I did some googling on JBOSS and I was expecting to find something on a APACHE like memory allocator suited for web processing.

  2. In the face of NUMA-esque architectures (potentially the near future) this sounds like a disaster unless the processes are CPU bound by thread and memory-allocation.

The answer is that this depends on the garbage collection algorithms used. In some cases, you are correct that all threads are stopped during GC. In other cases, you are incorrect in that garbage collection proceeds while normal threads are running. To understand how GC's achieve that, you need a detailed understanding of the theory and terminology of garbage collectors, combined with an understanding of the specific collector. It is simply not amenable to a simple explanation.

Oh yes, and it is worth pointing out that many modern collectors don't have a compaction phase per-se. Rather they work by copying live objects to a new "space" and zeroing the old "space" when they are done.

If I am incorrect my question would be answered by a simple explanation of the strategy used to minimise blocking.

If you really want to understand how garbage collectors work, I recommend:

... and beware that finding accurate, detailed, public descriptions of the internals of production garbage collectors is not easy. (Though in the case of the Hotspot GC's, you can look at the source code ...)

EDIT: in response to the OP's comment ...

"It seems it is as I thought -- there is no getting around the "stop the world" part."

It depends. In the case of the Java 6 Concurrent Collector, there are two pauses during the marking of the roots (including stacks), and then marking / copying of other objects proceeds in parallel. For other kinds of concurrent collector, read or write barriers are used while the collector is running to trap situations where the collector and application threads would otherwise interfere with each other. I don't have my copy of [Jones] here right now, but I also recall that it is possible to make the "stop the world" interval negligible ... at the cost of more expensive pointer operations and/or not collecting all garbage.