垃圾收集器行为相关问题查询

3

根据我在Sun内存管理白皮书中的阅读:

When stop-the-world garbage collection is performed, execution of the application is completely
suspended during the collection

如果垃圾收集器在运行时发生了请求,应用程序会如何处理呢?如果垃圾收集器时间太长,应用程序会抛出异常吗?我尚未遇到此类问题,但想知道是否可能,并将引发哪种异常?


我认为不会出现任何异常。 - codeMan
但如果正在进行网络操作,如果时间太长,肯定会出现某种形式的网络超时。那么这该如何处理呢? - DevZer0
2个回答

1
几乎所有的Java垃圾回收器都有某种形式的停顿阶段,其中所有Java线程都被暂停等待独占系统操作完成。这个状态有时被称为“安全点”。
现代垃圾收集器与应用程序线程同时运行,这意味着垃圾收集器在应用程序执行期间执行其工作。在垃圾收集器处理期间,需要独占访问内存的阶段,应用程序线程进入此“安全点”状态。
如果垃圾收集器无法恢复足够的内存以满足应用程序的分配需求,则会引发异常。
摆脱停止整个系统的垃圾回收的一种替代方法是选择使用Azul系统的C4收集器的Zing JVM。该实现采用低暂停方法,根本没有停止整个系统的垃圾回收。相反,它使用了一种并发压缩方法,没有停顿阶段。

一个线程在安全点之间可以持续多久?如果线程X处于安全点之间并且需要进行垃圾回收,那么是否需要所有其他线程停止,直到X到达下一个安全点,而不管回收需要多长时间? - supercat

0

这个垃圾回收器已经不再使用,被更好的垃圾回收器所取代。

stop-the-world 垃圾回收器会真正停止整个应用程序(所有线程),并清理堆。

当垃圾回收器需要太长时间(几乎从不发生)时,会抛出一个 Error

网络套接字上的传入流量会在回收器运行期间进行缓冲。


抛出了一个异常?我不知道!那会是哪个异常呢,@Uwe Plonus? - codeMan
如果任何垃圾收集器不能及时完成其任务,将抛出 OutOfMemoryError - Uwe Plonus
@UwePlonus:如果收集器是一个停止-全球收集器,它需要多长时间并不重要,因为程序已经停止,没有分配正在进行。如果垃圾回收完成其运行但无法回收任何空闲空间,则可能会出现OutOfMemoryError。 - davmac
@davmac,我已经遇到了几个OutOfMemoryError,并非由于堆空间耗尽引起的,例如java.lang.OutOfMemoryError: GC overhead limit exceeded.如果Java 7的默认垃圾收集器花费太多时间,则会抛出此异常。 - Uwe Plonus
@UwePlonus 我想我们两个都有点错了。如果垃圾回收需要很长时间,但只有在无法回收足够的空间时才会出现OutOfMemoryError。例如,请参见https://dev59.com/T2025IYBdhLWcg3wtobX - 当我说它无法回收任何空间时,我进行了概括。 - davmac
这个垃圾收集器 - 问题没有提到具体的垃圾收集器。即使是CMS也包括一些停顿全局的阶段,我想不出任何不进行停顿全局的年轻代收集器。 - piet.t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接