垃圾收集器-周志明先生的深入理解JVM摘录

原创 2014年12月07日 13:31:47

1   HotSpot的垃圾收集

        是基于分代的,不同代的内存区域根据其对象生命周期的长短特性选择不同的垃圾收集算法。HotSpot提供的垃圾收集器:

  

2   Parallel Scavenge收集器

      看周志明显示的《深入理解Java虚拟机》第三章垃圾收集器与内存分配,对Young generation的Parallel Scavenge和Tenured generation的CMS印象深刻,简单整理了下相关的知识。HotSpot的新生代由于生存时间较短,最终存活对象较少,适合拷贝清除算法,老年代由于对象存活时间较长,采用标记整理或者标记清除算法。

      Parallel Scavenge收集器,关注吞吐量,这种收集器中吞吐量和停顿时间是不可兼顾的两个方面,在共享CPU的情况下,这两个要素必定是此消彼长的。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值;停顿时间在单CPU系统中也是有GC时间的比率决定的。在Java进程中CPU时间由用户线程和GC回收线程轮换使用,二者的和构成了Java进程的CPU总消耗时间。Parallel Scavenge关注的两个要素的计算公式如下:

     吞吐量 throughtout=(运行用户代码的时间)/(运行用户代码的时间+垃圾收集时间)

     垃圾收集时间的占比=(垃圾收集时间)/(执行用户代码的时间+垃圾收集时间)

     停顿时间越短,说明GC消耗CPU时间越长,适合需要和用户交互的程序,能良好地提升用户的体验,另一方面用户代码执行时间也越短,系统吞吐量也越小,但是对用户响应速度也越高。而高吞吐量则可以高效利用CPU更快地完成用户的运算任务,主要适合后台运算交互较少的运用中。

     Parallel Scavenge提供了两个参数来精确控制吞吐量,-XX:MaxGCPauseMills,-XX:GCTimeRatio。前者是控制最大垃圾手机停顿时间的毫秒;后者是控制垃圾收集时间在CPU总消耗时间的占比的。GCTimeRatio的默认值是99,这个值的设置,我是这么理解的:就是你期望用户代码的CPU消耗时间和GC的CPU消耗时间的比例。在该收集器中,默认的值是99,即总CPU时间中,用户CPU时间:GC CPU时间=99:1,则GC时间占据总CPU时间的比例为1/(1+99)=1%。

    结论,所谓的GCTimeRatio,就是(用户程序CPU时间):(GC CPU时间),通过这个值,可以计算出GC时间在总CPU时间的比率。

    ParNew和Parallel Scavenge的区别是,后者关注的是系统吞吐量,也称为吞吐量优先的收集器。会跟当前系统的运行情况收集性能监控信息,动态调整某些参数,以提供最合适的停顿时间或者最大的吞吐量。自适应调节策略是其与ParNew的一个重要区别。

3 CMS收集器

       并发标记清除收集器,在多处理器的系统中才能发挥其优势,此时用户线程和GC线程可以在不同的CPU上运行,在CMS并发清理阶段,用户线程还在运行,这存在两个问题:首先,用户线程运行过程中还会产生新的垃圾,但此时CMS已经开始,这些新垃圾并未标记,无法在此次GC中收集,也称为“浮动垃圾”;其次,用户线程既然要运行,就必须有足够的内存空间,所以CMS收集Old区时必须保证为用户线程预留足够的内存。

     CMS收集Old区是在Old的使用空间到达一定的比例后就被触发的(不像其它的收集是在Old区几乎完全塞满时才进行),这样确保用户线程有足够的空间。控制参数是:-XX:CMSInitiatingOccupancyFraction,当用户进程在CMS运行过程中出现内存不足时会出现“Concurrent Mode Failure",JVM的后备方案就发生作用,以Serial Old方式重新收集Old区(暂停用户线程)。这个参数设置过高,容易导致用户线程运行过程中内存不足而出现Concurrent Mode Failure。

     CMS是采用标记清除的收集算法,还有一个缺点是容易产生空碎片,CMS提供了两个参数来解决这个问题。-XX:UseCMSCompactAtFullCollection开关参数(默认是开启),如果CMS出现无法分配连续内存时,对碎片内存进行整理。-XX:CMSFullGCsBeforeCompation,默认值为0,表示每次进入FullGC之前执行多少次不压缩的GC后跟着执行一次碎片整理。

      我的理解是,在CMS默认的参数下,其实CMS已经不是标记清除算法,而是标记整理算法了,我在想为什么一开始不直接使用标记整理算法呢?仔细想想,CMS其实是提供了动态调节算法的机制,应该可以综合获取这两种算法共同的优势,在特定场景下相互切换,以达到最好的效果。

     结论:不得不佩服设计这周详的考虑,对存在的问题提供解决方案和应急预案,CMS里面的优秀理念,受教了!

   


版权声明:本文为博主原创文章,未经博主允许不得转载。

深入理解Java 虚拟机(周志明)笔记(五)——垃圾收集器(二)

5.1.2.HotSpot的算法实现                可达性分析算法                   1.枚举根节点(GC Roots)                    ...

深入理解Java 虚拟机(周志明)笔记(五)——垃圾收集器(三)

5.1.3.垃圾回收的具体实现————垃圾收集器.               有一个垃圾收集器是最好的。不同垃圾收集器适合不同的环境。不同收集器可搭配使用,已达到整体最优。           ...

深入理解JVM(三)——垃圾收集器

需要了解GC吗?Q:需要了解GC和内存分配吗? A:当需要排查各种内存溢出,内存泄露问题时;当垃圾回收成为系统高并发的瓶颈时哪些内存需要回收?程序计数器,虚拟机栈,本地方法栈随着线程生而生,线程灭而...

深入理解JVM之垃圾收集器与内存分配策略

读完JVM的第三章最大的收获是知道了垃圾收集的算法,了解了JDK1.7中提供的垃圾收集器的特点以及运作原理,通过代码实例验证了Java虚拟机中自动分配内存及回收的主要规则。了解了内存回收与垃圾收集器在...

深入理解JVM(四)——各个版本提供的垃圾收集器

上一篇将的回收算法是内存回收的方法论,本篇讲垃圾收集器的具体实现,Java虚拟机规范并没有对齐做出规定和限制,所以不同厂商,不同版本的虚拟机,垃圾收集器有很大的区别。 收集器名称 区域 说...

[课本划重点]深入理解jvm-第3章 垃圾收集器与内存分配策略(2)

先吐槽:欠了鸟哥的更新还给你! -------------------划重点------------------------- 1垃圾收集算法 1.1标记-清除(标记过程参见上一节) ♦️统一...

深入理解JVM笔记二---垃圾收集器及内存分配策略

对象已死么?1.引用计数算法给对象中添加一个引用计数器,每当有一个地方引用它,计数器值就加1;当引用时效的时候,减一。任何时候计数器为0的对象就是不可能再被引用的。(很难解决对象之间相互循环引用的问题...

深入理解Java虚拟机JVM高级特性与最佳实践阅读总结——第三章垃圾收集器与内存分配策略

引用计数法:给对象添加引用计数器,每当有一个地方引用它时,计数器值加1,;引用失效则计数器值减一,任何计数值为0的对象就是不可能被使用的 特点:简单高效,但不能解决对象之间的循环引用 可达性分析算...

[jjzhu学java]之深入理解JVM之垃圾收集器与内存分配策略

深入理解JVM之垃圾收集器与内存分配策略 如何判断对象已经消亡 引用计数算法 根搜索算法 深入理解JVM之垃圾收集器与内存分配策略 java中对象的创建需要的内存都是在java...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:垃圾收集器-周志明先生的深入理解JVM摘录
举报原因:
原因补充:

(最多只允许输入30个字)