【JVM】垃圾收集器和收集器的选择策略
前言:新生代的收集器有:Serial,ParNew,Parallel Scavenge等。老年代有:CMS,SerialOld,Paraller Old等。接下来将深入理解各个垃圾收集器的原理,以及它们如何在不同场景下进行搭配使用。
同时,先解释几个名次:
- 并行(Parallel):多个垃圾收集线程并行工作,此时用户线程处于等待状态
- 并发(Concurrent):用户线程和垃圾收集线程同时执行
- 吞吐量:运行用户代码时间/(运行用户代码时间+垃圾回收时间)
(一) 新生代的收集器们
(1) ParNew
这是Serial收集器的多线程版本,使用多线程对垃圾收集,采用复制算法,同时需要暂时所有用户线程。除了使用多线程其他与Serial收集器相比并没有什么创新。但是为什么还要学习它,那是因为除了Serial收集器,目前只有它能与CMS收集器配合工作。因此我们在Server中虚拟机首选项的新生代收集器还是它。可以使用的控制参数有:-XX:SurvivorRatio,-XX:PretenureSizeThreshold,-XX:HandlerPromotionFailure等(详情见官方手册)。
(2) Parallel Scavenge收集器
使用复制算法,同时也是并行收集器,相比ParNew,它更关注于达到一个可控制的吞吐量。高吞吐量可以高效率地利用CPU时间,尽快完成计算任务。所以这个收集器适合在后台运算而不需要很多交互的任务。接下来看看两个用于准备控制吞吐量的参数
1,-XX:MaxGCPauseMills(控制最大垃圾收集的时间)
设置一个大于0的毫秒数,收集器尽可能地保证内存回收不超过设定值。但是并不是设置地越小就越快。GC停顿时间缩短是以缩短吞吐量和新生代空间来换取的。
2,-XX:GCTimeRatio(设置吞吐量大小)
设置一个0-100的整数,也就是垃圾收集时间占总时间的比率,相当于吞吐量的倒数。
(二) 老年队的收集器们
(1) Serial Old
是Serial收集器的老年队版本,也是一个单线程收集器,使用标记-整理算法。这个收集器主要在于给Client模式下的虚拟机使用。如果在Server中,主要用途是:1,在JDK1.5前和Parallel Scavenge搭配使用。2,作为Concurrent Mode Failure时候使用。
(2)Parallel Old
这是Paraller Scanvenge收集器的老年队收集器,使用标记-整理方式。在这个方式没有产生之前,Parallel Scavenge只能选择Serial Old。由于被拖了后腿,那么Parallel Scavenge并不能在整体上获取吞吐量最大化的效果。甚至比不上CMS+ParNew的吞吐量。
(3)CMS收集器
这是一个以获取最短回收停顿时间为目标的并发收集器。对于重视服务响应时间,希望系统停顿时间尽可能短的,那么CMS就非常符合了。CMS收集器采用标记-清除实现。包括了四个步骤
1,初始标记:简单标记下GC Roots能直接关联到的对象,需要“Stop The World“
2,并发标记:进行GC Roots Tracing
3,重新标记:修正并发标记期间用户程序继续运行而导致标记发生变动那一部分对 象标记记录,需要“Stop The World“
4,并发清除
缺点:
1,无法处理浮动垃圾。由于并发清理阶段用户线程还在运行,程序自然会有新的垃圾产生,那么CMS将无法在这次收集中处理掉它们。只能等待下次GC再清理。由于垃圾回收阶段用户线程还需要运行。那么就需要预留足够的内存空间给用户线程使用,所以CMS不能等待老年队几乎完全快满了再进行收集。需要预留一部分空间提供并发收集时候的程序使用。如果运行期间预留的内存无法满足程序需要,那么就会出现“Concurrent Mode Failure“,这时候就启用Serial Old收集器进行老年代的收集。
2,对CPU资源敏感。在并发阶段虽然不会导致用户线程停顿,但是会因为占用一部分线程(或者说CPU资源)而导致应用程序变慢,吞吐量降低,默认是启动(CPU数量+3)/4的线程数。
3,会产生大量的空间碎片。CMS是基于标记-清除算法实现的,那么收集结束时候会有大量空间碎片产生。这个时候就会给大对象分配带来麻烦,因为无法找到足够大的连续空间来分配当前对象,不得不提前触发一次Full GC。那么我们可以使用:-XX:+UseCMSCompactAtFullCollection,在CMS收集器顶不住要进行FullGC时候开启内存碎片的合并整理过程,但是会加长停顿时间。还有一个参数 -XX:CMSFullGCsBeforeCompaction,表示用于设置执行多少次不压缩的Full GC后,跟着来一次带压缩的。
(三) 垃圾收集器选择的策略
(1) 吞吐量优先的并行收集器
参数配置:
1, -Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:ParallelGCThreads=8
说明:选择Parallel Scavenge收集器,然后配置多少个线程进行回收,最好与处理器数目相等。
2,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:ParallelGCThreads=8 -XX:+UseParallelOldGC
说明:配置老年代使用Parallel Old
3,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:MaxGCPauseMills=100
说明:设置每次年轻代垃圾回收的最长时间。如何不能满足,那么就会调整年轻代大小,满足这个设置
4,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseParallelGC -XX:MaxGCPauseMills=100 -XX:+UseAdaptiveSizePolicy
说明:并行收集器会自动选择年轻代区大小和Survivor区的比例。
(2)响应时间优先的并发收集器
1, -Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
说明:设置老年代的收集器是CMS,年轻代是ParNew
2,-Xmx4g -Xms4g -Xmn2g -Xss200k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection
说明:首先设置运行多少次GC后对内存空间进行压缩,整理。同时打开对年老代的压缩(会影响性能)
转自:https://blog.csdn.net/KilluaZoldyck/article/details/75081875
【JVM】垃圾收集器和收集器的选择策略的更多相关文章
- JVM垃圾收集器-ParNew收集器
今天我给大家讲讲ParNew收集器. ParNew收集器 ParNew收集器收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参 ...
- JVM GC系列 — GC收集器
一.前言 前文学习了各种GC回收算法,掌握了GC回收的原理,但是真正的GC实现却尤为复杂,本篇文章将主要介绍各种GC收集器. 目前主流的HotSpot VM支持多种虚拟机,这些虚拟机也体现了GC的发展 ...
- [四] java8 函数式编程 收集器浅析 收集器Collector常用方法 运行原理 内部实现
Collector常见用法 常用形式为: .collect(Collectors.toList()) collect()是Stream的方法 Collectors 是收集器Collect ...
- JVM垃圾收集器-Serial收集器
今天我给大家分享的是Serial收集器,垃圾收集器就是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同的版本的虚拟机所提供的垃圾收集器都可能会有很大 ...
- JVM垃圾收集器-G1收集器
G1收集器是当前收集器技术发展的最前沿成果,在JDK1.6_Updata14中提供了Early Access版本的G1收集器以供适用.G1收集器是垃圾收集器理论进一步发展的产物,它与前面的CMS收集器 ...
- JVM 经典垃圾收集器 —— CMS 收集器
本文部分摘自<深入理解 Java 虚拟机第三版> 概述 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器.由于大部分 Java 应用主要 ...
- JVM探秘4---垃圾收集器介绍
Java虚拟机有很多垃圾收集器 下面先来了解HotSpot虚拟机中的7种垃圾收集器:Serial.ParNew.Parallel Scavenge.Serial Old.Parallel Old.CM ...
- JVM之Parallel Scavenge收集器
新生代收集器,复制算法,并行收集,面向吞吐量要求(吞吐量优先收集器). 吞吐量=用户代码运行时间/(用户代码运行时间+垃圾回收时间) -XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间 ...
- 深入理解JVM(③)ZGC收集器
前言 ZGC是一款在JDK11中新加入的具有实验性质的低延迟垃圾收集器,目前仅支持Linux/x86-64.ZGC收集器是一款基于Region内存布局的,(暂时)不设分代的,使用了读屏障.染色指针和内 ...
随机推荐
- P3956棋盘
传送 这看起来有点像个搜索,那我们就用搜索试试. dfs?bfs? 其实都可以,但是窝只会dfs.. 既然这里要用dfs,那么就要把每次搜到(m,m)时,使用的金币数量进行比较,取最小值. 在搜索过程 ...
- r_action
皮尔逊相关系数 斯皮尔曼等级相关(Spearman Rank Correlation) http://wiki.mbalib.com/wiki/斯皮尔曼等级相关 从表中的数字可以看出,工人的考试成绩愈 ...
- redhat 修改yum源
问题现象: 现有的yum安装git失败,提示yum源连接失败 Error Downloading Packages: git--.el6_4..x86_64: failure: Packages/gi ...
- java sftp.exec无法执行mv命令
编写java程序过程中,sftp上传下载建目录删除文件都可以,就是备份不行. 分析原因如下: 1.如果用的同一个用户,即sftp用户来通过 exec(ssh连接) 执行mv命令,那极有可能是在搭建sf ...
- 【SD系列】SAP SD模块-创建供应商主数据BAPI
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SD系列]SAP SD模块-创建供应商主数据B ...
- 全文搜索 ElasticSearch
今天突然想了解一下ES,看看有什么优势,能不能用在项目中. 说到ES就不得不了解它的底层技术-全文检索 Ref: 全文检索的基本原理 https://blog.csdn.net/wangmaohong ...
- Orcle获取当前时间加小时
如下是oracle 获取当前数据库时间加2个小时 select to_date(TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh24: ...
- python之字符串的切片
切片操作(slice)可以从一个字符串中获取子字符串(字符串的一部分).我们使用一对方括号.起始偏移量start.终止偏移量end 以及可选的步长step 来定义一个分片. 格式: [start:en ...
- instanceof 和isinstance的区别
class A {} class B extends A {} class C extends A {} public class Test { public static void main(Str ...
- js 为false的几种情况
1: false 2: null 3:undefined 4:"" 空字符串 5:0 6:NaN 如果你的if条件里面会出现 0 或者"",那么这种肯定是为假的 ...