如何判定一个对象是否应该回收?以及CMS垃圾回收器和G1收集器的特点

       前文我们聊了垃圾回收的算法,那么我们现在来看一下,如何判定一个对象时垃圾。举个例子

Person p = new Person();
p = null;//此时的p是不是已经是一个垃圾

       为了解决循环引用的问题,java中采取了正向可达的方式,主要是通过Roots对象作为起点进行搜索,搜索走过的路径称为“引用链”,当一个对象到 Roots 没有任何的引用链相连时时,证明此对象不可用,当然被判定为不可达的对象不一定就会成为可回收对象。

       被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了,能否被回收其实主要还是要看finalize()方法有没有与引用链上的对象关联,如果在finalize()方法中有关联则自救成功,改对象不可被回收,反之如果没有关联则成功被二次标记成功,就可以称为要被回收的垃圾了。

      除了垃圾回收,还有那些工作会造成CPU负载过高(其实这里给出的是一个场景,就是让描述一下除了垃圾回收之外,还有那些工作会让线上CPU占用到百分之90-100,并且给出排查过程。)。

说一下CMS垃圾回收器和G1收集器的特点,和收集过程。

  1. CMS收集器是一种以获取最短回收停顿时间为目标的收集器。基于“标记-清除”算法实现,它的运作过程如下:

    • 初始标记

    • 并发标记

    • 重新标记

    • 并发清除

  • 初始标记、从新标记这两个步骤仍然需要“stop the world”,初始标记仅仅只是标记一下GC Roots能直接关联到的对象,熟读很快,
  • 并发标记阶段就是进行GC Roots Tracing,
  • 重新标记阶段则是为了修正并发标记期间因用户程序继续运作而导致标记产生表动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长点,但远比并发标记的时间短。
  1. CMS是一款优秀的收集器,主要优点:并发收集、低停顿。

      缺点:
    
    • CMS收集器对CPU资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程而导致应用程序变慢,总吞吐量会降低。

    • CMS收集器无法处理浮动垃圾,可能会出现“Concurrent Mode Failure(并发模式故障)”失败而导致Full GC产生。

    • 浮动垃圾:由于CMS并发清理阶段用户线程还在运行着,伴随着程序运行自然就会有新的垃圾不断产生,这部分垃圾出现的标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次GC中再清理。这些垃圾就是“浮动垃圾”。

    • CMS是一款“标记–清除”算法实现的收集器,容易出现大量空间碎片。当空间碎片过多,将会给大对象分配带来很大的麻烦,往往会出现老年代还有很大空间剩余,但是无法找到足够大的连续空间来分配当前对象,不得不提前触发一次Full GC。

  2. G1是一款面向服务端应用的垃圾收集器。G1具备如下特点:

    • 并行于并发:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让java程序继续执行。

    • 分代收集:虽然G1可以不需要其他收集器配合就能独立管理整个GC堆,但是还是保留了分代的概念。它能够采用不同的方式去处理新创建的对象和已经存活了一段时间,熬过多次GC的旧对象以获取更好的收集效果。

    • 空间整合:与CMS的“标记–清理”算法不同,G1从整体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。

    • 可预测的停顿:这是G1相对于CMS的另一个大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,

G1运作步骤:

1、初始标记;2、并发标记;3、最终标记;4、筛选回收

发布了320 篇原创文章 · 获赞 152 · 访问量 64万+

猜你喜欢

转载自blog.csdn.net/hello_word2/article/details/105004525