概述
Jvm中存在几种收集算法,那么GC究竟是在什么时候执行的呢?
串行收集器(Serial)
优点:
- 最古老,最稳定
- 效率高
缺点:
- 可能会产生较长的停顿
使用:
- -XX:+UseSerialGC
- 新生代、老年代使用串行回收
- 新生代复制算法
- 老年代标记-压缩
执行过程,如上图,因此会产生Jvm全局停顿的效果。
并行收集器
ParNew
- -XX:+UseParNewGC
- 新生代并行
- 老年代串行
- Serial收集器新生代的并行版本
- 复制算法
- 多线程,需要多核支持
- -XX:ParallelGCThreads 限制线程数量,一般为CPU核数
多线程执行也会产生Jvm全局停顿,但是多线程不一定比单线程处理效果更好,如果分配不当,多线程甚至会比单线程更慢。
Parallel
- 新生代使用 复制 算法
- 老年代使用 标记-压缩 算法
- 更加关注吞吐量
- -XX:+UseParallelGC
- 使用Parallel收集器+ 老年代串行
- -XX:+UseParallelOldGC
- 使用Parallel收集器+ 并行老年代
GC参数:
- -XX:MaxGCPauseMills
- 最大停顿时间,单位毫秒
- GC尽力保证回收时间不超过设定值
- -XX:GCTimeRatio
- 0-100的取值范围
- 垃圾收集时间占总时间的比
- 默认99,即最大允许1%时间做GC
这两个参数是矛盾的。因为停顿时间和吞吐量不可能同时调优,如果设置最大停顿时间过短,那么将会导致大量的死亡对象没有被回收,因此Jvm将会在达到一定程度时,进行彻底的回收一次,那么将会导致大量的Jvm全局时间停顿。
CMS收集器
- Concurrent Mark Sweep 并发标记清除
- 标记-清除算法
- 与标记-压缩相比,并发阶段会降低吞吐量
- 老年代使用Parller收集器,新生代使用ParNew
- -XX:+UseConcMarkSweepGC
收集过程:
- 初始标记
- 标记根可以直接关联到的对象
- 并发标记(和用户线程一起)
- 主要标记过程,标记全部对象
- 重新标记
- 由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
- 并发清除(和用户线程一起)
- 基于标记结果,直接清理对象
特点:
- 尽可能降低停顿
- 会影响系统整体吞吐量和性能
- 比如,在用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半
- 清理不彻底
- 因为在清理阶段,用户线程还在运行,会产生新的垃圾,无法清理
- 因为和用户线程一起运行,不能在空间快满时再清理
- -XX:CMSInitiatingOccupancyFraction设置触发GC的阈值
- 如果不幸内存预留空间不够,就会引起concurrent mode failure
参数设置:
- -XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次整理,整理过程是独占的,会引起停顿时间变长
- -XX:+CMSFullGCsBeforeCompaction :设置进行几次Full GC后,进行一次碎片整理
- -XX:ParallelCMSThreads:设定CMS的线程数量
G1垃圾收集器
常规的垃圾清理都需要进行全盘的扫描新生代和老年代的内存,所以耗费的时间一般比较久,但是G1采用了分区的概念,整个堆空间默认分为2048个分区,且分区不是物理概念,可以是物理区域不连续的逻辑区域。每个分区又分为大小为512Byte的卡片,每次对内存的回收,都是对指定的分区卡片进行处理。-XX:G1HeapRegionSize=n可指定分区的大小,且必须是2的幂数次方的数(1MB-32MB)。
分代:
年轻代在G1中不是固定不变的,默认动态变化范围为整个堆的5%,最大可以分配到60%
最后
以上就是动听太阳为你收集整理的常用GC讲解的全部内容,希望文章能够帮你解决常用GC讲解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复