第五章 JVM垃圾收集器(1)
说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见《第四章 JVM垃圾回收算法》
1、七种垃圾收集器
- Serial(串行GC)-- 复制
- ParNew(并行GC)-- 复制
- Parallel Scavenge(并行回收GC)-- 复制
- Serial Old(MSC)(串行GC)-- 标记-整理
- CMS(并发GC)-- 标记-清除
- Parallel Old(并行GC)--标记-整理
- G1(JDK1.7update14才可以正式商用)
说明:
- 1~3用于年轻代垃圾回收:年轻代的垃圾回收称为minor GC
- 4~6用于年老代垃圾回收(当然也可以用于方法区的回收):年老代的垃圾回收称为full GC
- G1独立完成"分代垃圾回收"
注意:并行与并发
- 并行:多条垃圾回收线程同时操作
- 并发:垃圾回收线程与用户线程一起操作
2、常用五种组合
- Serial/Serial Old
- ParNew/Serial Old:与上边相比,只是比年轻代多了多线程垃圾回收而已
- ParNew/CMS:当下比较高效的组合
- Parallel Scavenge/Parallel Old:自动管理的组合
- G1:最先进的收集器,但是需要JDK1.7update14以上
2.1、Serial/Serial Old:
特点:
- 年轻代Serial收集器采用单个GC线程实现"复制"算法(包括扫描、复制)
- 年老代Serial Old收集器采用单个GC线程实现"标记-整理"算法
- Serial与Serial Old都会暂停所有用户线程(即STW)
说明:
- STW(stop the world):编译代码时为每一个方法注入safepoint(方法中循环结束的点、方法执行结束的点),在暂停应用时,需要等待所有的用户线程进入safepoint,之后暂停所有线程,然后进行垃圾回收。
适用场合:
- CPU核数<2,物理内存<2G的机器(简单来讲,单CPU,新生代空间较小且对STW时间要求不高的情况下使用)
- -XX:UseSerialGC:强制使用该GC组合
- -XX:PrintGCApplicationStoppedTime:查看STW时间
2.2、ParNew/Serial Old:
说明:
- ParNew除了采用多GC线程来实现复制算法以外,其他都与Serial一样,但是此组合中的Serial Old又是一个单GC线程,所以该组合是一个比较尴尬的组合,在单CPU情况下没有Serial/Serial Old速度快(因为ParNew多线程需要切换),在多CPU情况下又没有之后的三种组合快(因为Serial Old是单GC线程),所以使用其实不多。
- -XX:ParallelGCThreads:指定ParNew GC线程的数量,默认与CPU核数相同,该参数在于CMS GC组合时,也可能会用到
2.3、Parallel Scavenge/Parallel Old:
特点:
- 年轻代Parallel Scavenge收集器采用多个GC线程实现"复制"算法(包括扫描、复制)
- 年老代Parallel Old收集器采用多个GC线程实现"标记-整理"算法
- Parallel Scavenge与Parallel Old都会暂停所有用户线程(即STW)
说明:
- 吞吐量:CPU运行代码时间/(CPU运行代码时间+GC时间)
- CMS主要注重STW的缩短(该时间越短,用户体验越好,所以主要用于处理很多的交互任务的情况)
- Parallel Scavenge/Parallel Old主要注重吞吐量(吞吐量越大,说明CPU利用率越高,所以主要用于处理很多的CPU计算任务而用户交互任务较少的情况)
参数设置:
- -XX:+UseParallelOldGC:使用该GC组合
- -XX:GCTimeRatio:直接设置吞吐量大小,假设设为19,则允许的最大GC时间占总时间的1/(1+19),默认值为99,即1/(1+99)
- -XX:MaxGCPauseMillis:最大GC停顿时间,该参数并非越小越好
- -XX:+UseAdaptiveSizePolicy:开启该参数,-Xmn/-XX:SurvivorRatio/-XX:PretenureSizeThreshold这些参数就不起作用了,虚拟机会自动收集监控信息,动态调整这些参数以提供最合适的的停顿时间或者最大的吞吐量(GC自适应调节策略),而我们需要设置的就是-Xmx,-XX:+UseParallelOldGC或-XX:GCTimeRatio两个参数就好(当然-Xms也指定上与-Xmx相同就好)
注意:
- -XX:GCTimeRatio和-XX:MaxGCPauseMillis设置一个就好
- 不开启-XX:+UseAdaptiveSizePolicy,-Xmn/-XX:SurvivorRatio/-XX:PretenureSizeThreshold这些参数依旧可以配置,以resin服务器为例
<jvm-arg>-Xms2048m</jvm-arg>
<jvm-arg>-Xmx2048m</jvm-arg>
<jvm-arg>-Xmn512m</jvm-arg>
<jvm-arg>-Xss1m</jvm-arg>
<jvm-arg>-XX:PermSize=256M</jvm-arg>
<jvm-arg>-XX:MaxPermSize=256M</jvm-arg>
<jvm-arg>-XX:SurvivorRatio=8</jvm-arg>
<jvm-arg>-XX:MaxTenuringThreshold=15</jvm-arg> <jvm-arg>-XX:+UseParallelOldGC</jvm-arg>
<jvm-arg>-XX:GCTimeRatio=19</jvm-arg> <jvm-arg>-XX:+PrintGCDetails</jvm-arg>
<jvm-arg>-XX:+PrintGCTimeStamps</jvm-arg>
适用场合:
- 很多的CPU计算任务而用户交互任务较少的情况
- 不想自己去过多的关注GC参数,想让虚拟机自己进行调优工作
2.4、ParNew/CMS
说明:
- 以上只是年老代CMS收集的过程,年轻代ParNew看"2.2、ParNew/Serial Old"就好
- CMS是多回收线程的,不要被上图误导,默认的线程数:(CPU数量+3)/4
- CMS主要注重STW的缩短(该时间越短,用户体验越好,所以主要用于处理很多的交互任务的情况)
特点:
- 年轻代ParNew收集器采用多个GC线程实现"复制"算法(包括扫描、复制)
- 年老代CMS收集器采用多线程实现"标记-清除"算法
- 初始标记:标记与根集合节点直接关联的节点。时间非常短,需要STW
- 并发标记:遍历之前标记到的关联节点,继续向下标记所有存活节点。时间较长。
- 重新标记:重新遍历trace并发期间修改过的引用关系对象。时间介于初始标记与并发标记之间,通常不会很长。需要STW
- 并发清理:直接清除非存活对象,清理之后,将该线程占用的CPU切换给用户线程
- 初始标记与重新标记都会暂停所有用户线程(即STW),但是时间较短;并发标记与并发清理时间较长,但是不需要STW
关于并发标记期间怎样记录发生变动的引用关系对象,在重新标记期间怎样扫描这些对象,见《第六章 JVM垃圾收集器(2)》
缺点:
- 吞吐量降低 - 并发标记与并发清理:按照说明的第二点来讲,假设有2个CPU,那么其中有一个CPU会用于垃圾回收,而另一个用于用户线程,这样的话,之前是两CPU运行用户线程,现在是一个,那么效率就会急剧下降。也就是说,降低了吞吐量。
- 浮动垃圾 - 并发清理:在这一过程中,产生的垃圾无法被清理(因为发生在重新标记之后)
- 并发标记与并发清理:由于是与用户线程并发的,所以用户线程可能会分配对象,这样既可能对象直接进入年老代(例如,大对象),也可能进入年轻代后,年轻代发生minor GC,这样的话,实际上要求我们的年老代需要预留一定空间,也就是说要在年老代还有一定空间的情况下就要进行垃圾回收,留出一定内存空间来供其他线程使用,而不能等到年老代快爆满了才进行垃圾回收,通过-XX:CMSInitiatingOccupancyFraction来指定当年老代空间满了多少后进行垃圾回收,如果在回收过程中,老年代已经不够使用了,这时候CMS回收失败,老年代使用serial Old进行GC
- 垃圾碎片 - 标记-清理算法:会产生内存碎片,由于是在老年代,可能会提前触发Full GC(这正是我们要尽量减少的)
参数设置:
- -XX:+UseConcMarkSweepGC:使用该GC组合
- -XX:CMSInitiatingOccupancyFraction:指定当年老代空间满了多少后进行垃圾回收
- -XX:+UseCMSCompactAtFullCollection:(默认是开启的)在CMS收集器顶不住要进行FullGC时开启内存碎片整理过程,该过程需要STW
- -XX:CMSFullGCsBeforeCompaction:指定多少次FullGC后才进行整理
- -XX:ParallelCMSThreads:指定CMS回收线程的数量,默认为:(CPU数量+3)/4
适用场合:
- 用于处理很多的交互任务的情况
- 方法区的回收一般使用CMS,配置两个参数:-XX:+CMSPermGenSweepingEnabled与-XX:+CMSClassUnloadingEnabled
3、一些经验
- 由于当下大型企业用的比较多的还是jdk1.6版本,所以G1用的还是不多
- 用得最多的两种:ParNew/CMS和Parallel Scavenge/Parallel Old
- Full GC的四种情况
- 旧生代空间不足
- 不要创建过大的对象获数组
- 尽量让对象在minor GC被回收
- 让对象在年轻代多存活一段时间,可能这段时间内就会被minor GC回收
- 方法区满了
- 增大方法区
- 使用CMS GC回收方法区
- CMS GC中promotion failed(minor GC时,survivor区放不下,年老区也放不下)和concurrent mode failure
- 增大survivor区
- 增大年老区
- 调低-XX:CMSInitiatingOccupancyFraction
- 设置:-XX:CMSMaxAbortablePrecleanTime=5(单位:ms),防止CMS在重新标记很久后才进行并发清理
- 空间担保机制(这一块儿见《深入理解Java虚拟机(第二版)》P98)
- 旧生代空间不足
附:具体的配置参数查看《深入理解Java虚拟机(第二版)》P90
第五章 JVM垃圾收集器(1)的更多相关文章
- 第六章 JVM垃圾收集器(2)
上一章记录了几种常见的垃圾收集器,见<第五章 JVM垃圾收集器(1)> 1.G1 说明: 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除 ...
- JVM垃圾收集器(1)
此文已由作者赵计刚薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法& ...
- 5种JVM垃圾收集器特点和8种JVM内存溢出原因
先来看看5种JVM垃圾收集器特点 一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial O ...
- 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)
7种 JVM 垃圾收集器特点.优劣势及使用场景(多图) mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...
- JVM调优:HotSpot JVM垃圾收集器
HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html
- JVM垃圾收集器-Parallel Scavenge收集器
今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...
- 7种JVM垃圾收集器特点,优劣势、及使用场景
今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...
- 【006】【JVM——垃圾收集器总结】
Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...
- 深入理解JVM - 垃圾收集器与内存分配策略 - 第三章
引用计数算法——判断对象是否存活的算法 很多教科书判断对象是否存活的算法是这样的:给对象添加一个引用计数器,每当一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象 ...
随机推荐
- 【原创】Silverlight的ComboBox.SelectValue无法赋值
前几天开发中 给ComboBox的SelectValue属性赋值是,老是赋不上去.之前SelectValue为Null,执行完调试看下,还是Null.很诡异 ComboBox的SelectVa ...
- mvc view获取url参数
视图页面直接获取url get传值, 1.@Request.QueryString["look"] 2.@ViewContext.RequestContext.HttpContex ...
- (转)innodb 多版本并发控制原理详解
转自:https://blog.csdn.net/aoxida/article/details/50689619 多版本并发控制技术已经被广泛运用于各大数据库系统中,如Oracle,MS SQL Se ...
- css简单分页
html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...
- process_进程池
from multiprocessing import Poolimport os,timeimport multiprocessingdef func(msg): print("msg:& ...
- 体育类App原型制作分享-Onefootball
Onefootball 是一款适合于足球迷的应用,提供全球 100 多项赛事的新闻.数据.比分和直播.原型中选择“喜欢的球队”这个界面中,用到了悬浮按钮,采用的是滚动区来放置需要滚动的球队列表,然后将 ...
- 5条面经,助你成功拿到UX设计师Offer
为什么成为 UX设计师? 如果你经常逛推酷, 知乎, 设计达人或者一些专业的设计师论坛,博客,你会发现,第一批成为UX设计师的人,其实是误打误撞地落入这个行业的.那时候人们并不清楚UX设计师是什么 ...
- asp.net (jquery easy-ui datagrid)通用Excel文件导出(NPOI)
http://www.cnblogs.com/datacool/archive/2013/03/12/easy-ui_datagrid_export_excel_asp_net.html
- 简单的socket编程
1.socket 服务器搭建 实例化socket服务器,循环获取请求 package com.orange.util; import java.io.IOException; import java. ...
- 项目管理心得:一个项目经理的个人体会、经验总结(zz)
本人做项目经理工作多年,感到做这个工作最要紧的就是要明白什么是因地制宜.因势利导,只有最合适的,没有什么叫对的,什么叫错的,项目经理最忌讳 的就是完美主义倾向,尤其是做技术人员出身的,喜欢寻找标准答案 ...