![]() |
1
16
答案是,这取决于所使用的垃圾收集算法。在某些情况下,正确的做法是在GC期间停止所有线程。在其他情况下,在正常线程运行时进行垃圾收集是不正确的。要理解GC是如何实现这一点的,您需要对垃圾收集器的理论和术语有一个详细的理解,并结合对特定收集器的理解。简单的解释是不可接受的。 哦,是的,值得指出的是,许多现代收藏家本身并没有压缩阶段。相反,它们的工作方式是将活动对象复制到新的“空间”,并在完成后将旧的“空间”归零。
如果您真的想了解垃圾收集器的工作原理,我建议您:
…要注意,要找到生产垃圾收集器内部的准确、详细、公开的描述并不容易。(尽管在热点GC的情况下,您可以查看源代码…) 编辑: 为了回应行动党的评论…
这要看情况而定。在这种情况下 Java 6 Concurrent Collector 在标记根(包括堆栈)期间有两个停顿,然后标记/复制其他对象并行进行。对于其他类型的并发收集器,在收集器运行时使用读或写屏障来捕获收集器和应用程序线程在其他情况下会相互干扰的情况。我现在没有[琼斯]的拷贝,但我还记得有可能使“停止世界”的时间间隔变得微不足道…以更昂贵的指针操作和/或不收集所有垃圾为代价。 |
![]() |
2
2
正确的做法是垃圾收集器必须暂停所有应用程序线程。通过使用并发收集器(它在不停止应用程序的情况下执行某些工作),可以通过Sun JVM减少暂停时间,但它必须暂停应用程序线程。 看到这里 http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gc 这里 http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#cms 有关Sun JVM如何在最新的JVM中管理垃圾收集的详细信息。 对于Web应用程序,我不认为这是一个问题。由于用户请求应在很短的时间内完成,因此分配给服务的任何临时对象都不应退出年轻一代(前提是其大小适当),在那里它们被非常有效地清理。其他生命周期较长的数据(如用户会话)将停留更长时间,并可能影响在主要GC事件上花费的时间。 在高TPS应用程序上,一种常见的策略是使用会话关联和负载平衡在同一个或单独的硬件上运行应用程序服务器的多个实例。通过这样做,每个JVM的单独堆大小保持较小,从而在执行主集合时减少GC的暂停时间。通常,数据库成为瓶颈,而不是应用程序或JVM。 在J2EE中,最接近Web特定内存分配器概念的是由框架和应用程序服务器执行的对象/实例池。例如,在JBoss中,您有EJB池和数据库连接池。然而,这些对象通常是因为创建成本更高而不是垃圾收集开销。 |
![]() |
3
1
我相信IBM已经对改善多核系统中的GC性能进行了一些研究,其中包括减少或消除“一切都停止”的问题。 例如: A Parallel, Incremental and Concurrent GC for Servers(pdf) 或者谷歌,比如“并发垃圾收集IBM” |
![]() |
4
1
Sun的Hotspot JVM和Microsoft的CLR都有并发的GCS,它们只在短时间内(以获取所有实时数据可从中访问的全局根的自一致快照)而不是整个收集周期内停止全球通信。我不确定它们的压缩实现,但这是非常罕见的。
这些引擎的延迟比停止世界所需的时间要长几个数量级。此外,延迟被引用为,例如,第95个百分点,意味着延迟将只低于所引用时间跨度的95%。所以压缩不太可能影响引用的延迟。 |
![]() |
5
0
有许多可用Java的GC算法,并不是所有的算法都阻塞了所有运行的线程。例如,您可以使用-xx:+useconcmarkswepgc,它与应用程序同时运行(用于永久生成的集合)。 |
![]() |
6
0
目前Java的垃圾回收的现状仍然涉及到“停止世界”的暂停。在Java6U14上引入的G1 GC大部分都是同时工作的,但是,当内存非常低时,它需要压缩堆,那么它必须确保没有人在它下面堆。这要求不允许进行任何其他操作。要了解关于g1 gc的更多信息,请查看 presentations from Sun . |
![]() |
codeforester · 测量GC暂停时间的最佳方法是什么? 6 年前 |
![]() |
Venki WAR · 需要解释G1的并行完整GC 6 年前 |
![]() |
Stephan_Berlin · 为什么CMS系列中的初始标记阶段 6 年前 |
![]() |
Bonsaisteak · 为什么年轻一代需要三个区域来收集垃圾? 6 年前 |
![]() |
goks · 如何清除熊猫的数据帧内存? 7 年前 |