前言:新生代的收集器有: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. curry柯里化

    Function.prototype.method = function(name,func){ if(!this.prototype[name]){ this.prototype[name] = f ...

  2. 软件-Jenkins:Jenkins 百科

    ylbtech-软件-Jenkins:Jenkins 百科 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续 ...

  3. day23—JavaScript实现DIV盒子拖拽(原生方式)

    转行学开发,代码100天——2018-04-08 <!doctype html> <html> <head> <meta charset="utf- ...

  4. PHP 调试 - Xdebug

    PHP 调试指南.pdf PHP 程序员的调试技术 根据要调试的对象的不同,采取的方法也不一样: 调试 web 应用:对于 web 应用,可以在浏览器中安装插件,或者在 IDE 中设置,下面的设置二选 ...

  5. Vagrant 手册之 Provisioning - 基本用法

    原文地址 虽然 Vagrant 提供了用于配置虚拟机的多个选项,但是有标准用法,好多知识点对这个 provisioner 是通用的. 配置 首先,Vagrantfile 中配置的每个 provisio ...

  6. Vagrant 手册之 Provisioning - File

    原文地址 Provisioner 名字:"file" Vagrant 的 file provisioner 允许将文件或目录从主机上传到客户机. File provisioning ...

  7. Android深度探索-卷1第七章心得体会

    创建LED驱动的设备文件 第一步:使用cdev_init函数初始化cdev 第二步:指定设备号.直接在代码指定或动态分配 第三步:使用cdev_add函数将字符设备添加到内核中的字符设备数组中 第四步 ...

  8. HashMap和布隆过滤器命中性能测试

    package datafilter; import com.google.common.base.Stopwatch; import com.google.common.hash.BloomFilt ...

  9. Codeforces 1105D (BFS)

    题面 传送门 分析 考虑BFS while(棋盘没有满){ for 玩家 p{ 对p进行BFS,走s[p]步 } } 对于每个玩家p BFS的时候如果到了格子(x,y),就把\(vis[x][y]\) ...

  10. 9、numpy——数组操作

    Numpy 中包含了一些函数用于处理数组,大概可分为以下几类: (1)修改数组形状 (2)翻转数组 (3)修改数组维度 (4)连接数组 (5)分割数组 (6)数组元素的添加与删除 1.修改数组形状 函 ...