前言:新生代的收集器有:Serial,ParNew,Parallel Scavenge等。老年代有:CMS,SerialOld,Paraller Old等。接下来将深入理解各个垃圾收集器的原理,以及它们如何在不同场景下进行搭配使用。
同时,先解释几个名次:

  1. 并行(Parallel):多个垃圾收集线程并行工作,此时用户线程处于等待状态
  2. 并发(Concurrent):用户线程和垃圾收集线程同时执行
  3. 吞吐量:运行用户代码时间/(运行用户代码时间+垃圾回收时间)

(一) 新生代的收集器们

(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】垃圾收集器和收集器的选择策略的更多相关文章

  1. JVM垃圾收集器-ParNew收集器

    今天我给大家讲讲ParNew收集器. ParNew收集器 ParNew收集器收集器其实就是Serial收集器的多线程版本,除了使用多线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参 ...

  2. JVM GC系列 — GC收集器

    一.前言 前文学习了各种GC回收算法,掌握了GC回收的原理,但是真正的GC实现却尤为复杂,本篇文章将主要介绍各种GC收集器. 目前主流的HotSpot VM支持多种虚拟机,这些虚拟机也体现了GC的发展 ...

  3. [四] java8 函数式编程 收集器浅析 收集器Collector常用方法 运行原理 内部实现

    Collector常见用法     常用形式为:   .collect(Collectors.toList()) collect()是Stream的方法 Collectors  是收集器Collect ...

  4. JVM垃圾收集器-Serial收集器

    今天我给大家分享的是Serial收集器,垃圾收集器就是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同的版本的虚拟机所提供的垃圾收集器都可能会有很大 ...

  5. JVM垃圾收集器-G1收集器

    G1收集器是当前收集器技术发展的最前沿成果,在JDK1.6_Updata14中提供了Early Access版本的G1收集器以供适用.G1收集器是垃圾收集器理论进一步发展的产物,它与前面的CMS收集器 ...

  6. JVM 经典垃圾收集器 —— CMS 收集器

    本文部分摘自<深入理解 Java 虚拟机第三版> 概述 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器.由于大部分 Java 应用主要 ...

  7. JVM探秘4---垃圾收集器介绍

    Java虚拟机有很多垃圾收集器 下面先来了解HotSpot虚拟机中的7种垃圾收集器:Serial.ParNew.Parallel Scavenge.Serial Old.Parallel Old.CM ...

  8. JVM之Parallel Scavenge收集器

    新生代收集器,复制算法,并行收集,面向吞吐量要求(吞吐量优先收集器). 吞吐量=用户代码运行时间/(用户代码运行时间+垃圾回收时间) -XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间 ...

  9. 深入理解JVM(③)ZGC收集器

    前言 ZGC是一款在JDK11中新加入的具有实验性质的低延迟垃圾收集器,目前仅支持Linux/x86-64.ZGC收集器是一款基于Region内存布局的,(暂时)不设分代的,使用了读屏障.染色指针和内 ...

随机推荐

  1. PHP Trait特性

    php类的单继承性,无法同时从两个基类中继承属性和方法,为了解决这个问题,使用Trait特性解决. Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码复用机制. 用法:通过在类中使 ...

  2. CodeForces - 587E[线段树+线性基+差分] ->(线段树维护区间合并线性基)

    题意:给你一个数组,有两种操作,一种区间xor一个值,一个是查询区间xor的结果的种类数 做法一:对于一个给定的区间,我们可以通过求解线性基的方式求出结果的种类数,而现在只不过将其放在线树上维护区间线 ...

  3. 小程序的开发框架MINA及小程序的启动机制

    MINA框架分三个部分 视图层(View):有很多页面,每个页面有wxml和wxss组成的,视图结构和展现样式 逻辑层(App Service):处理事物逻辑的地方以及数据交互的服务中心 系统层(Na ...

  4. 洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    洛谷P1879 [USACO06NOV]玉米田Corn Fields \(f[i][j]\) 表示前 \(i\) 行且第 \(i\) 行状态为 \(j\) 的方案总数.\(j\) 的大小为 \(0 \ ...

  5. 表单修饰符 number、trim、lazy

    number修饰符 <input type="number" v-model.number="age"> 结论:age 类型则为number,非字符 ...

  6. 常用的Android关键词定位方法

    1字符串,特征字 根据程序运行中出现的特征字词进行搜索,从而获取定位到程序的相关位置之中.以前用 得比较多,不过现在一般难以找到想要的关键词.有时候需要对特征字进行拆分来进行搜索.才 能获得一点提示. ...

  7. 当主机ip变了修改gitlab的ip地址

    gitlab服务器IP地址更换后需要修改以下两个配置中的IP地址: /var/opt/gitlab/gitlab-rails/etc/gitlab.yml /etc/gitlab/gitlab.rb ...

  8. Aliyun mysql配置 远程访问 10038

    环境 centos7.2    mysql5.7 网上搜了好多的文章,有的说在/etc/my.cnf 注释掉bind-address = 127.0.0.1 ,也开启了3306端口的防火墙,也添加了远 ...

  9. POJ 3281 网络流 拆点保证本身只匹配一对食物和饮料

    如何建图? 最开始的问题就是,怎么表示一只牛有了食物和饮料呢? 后来发现可以先将食物与牛匹配,牛再去和饮料匹配,实际上这就构成了三个层次. 起点到食物层边的容量是1,食物层到奶牛层容量是1,奶牛层到饮 ...

  10. Phone-java标准类

    //project-module-package //.代表包的目录层次 package cn.learn.day01.demo01; /* 1.类是一组相关属性(成员变量)与行为(方法)的集合,对象 ...