Java中的垃圾回收器的类型概述 《对Java的分析总结》(六)
1、垃圾收集器的类型
从不同的角度来分析垃圾收集器,可能将其分为不同的类型
1./垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法、火车算法)的具体实现
2.不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别
1 垃圾收集器的类型
类别 | 垃圾回收器类型 | 描述 |
1 线程数 | 并行垃圾回收器 | 一次将开启多个线程开始进行垃圾回收 |
串行垃圾回收器 | 一次只执行一个线程进行垃圾回收 | |
2 工作模式 | 并发垃圾回收器 | 并发式垃圾回收器与应用程序交替工作,以尽可能减少应用程序的停顿时间 |
独占垃圾回收器 | 一 旦运行,就停止应用程序中的所有的其他线程 | |
3 碎片处理方式 | 压缩垃圾回收器 | 在回收完后,对存活对象进行压缩整理,清除回收后的碎片 |
非压缩垃圾回收器 | 不进行碎片整理 | |
4 分代(工作的内存区间) | 新生代 | – – |
老年代 | – |
3 串行收集器
串行收集器进行垃圾回收时,Java应用程序中的线程都需要暂停,等待垃圾回收的完成
3.1 老年代串行收集器
老年代串行收集器采用 标记 - 压缩 算法,是一个串行的 独占式的垃圾回收器,在堆空间较大的应用程序中,一旦启动,应用程序很可能会因此停顿几秒甚至更长
老年代串行收集器可以与多种新生代垃圾回收器配合使用
启用老年代串行回收器配制参数参考
key | value | 描述 |
---|---|---|
-XX | +UseSerialGC | 新生代 老年代都使用串行回收器 |
-XX | +UseParNewGC | 新生代使用并行回收收集器 老年代都使用串行回收器 |
-XX | +UseParallelGC | 新生代使用并行回收收集器 老年代都使用串行回收器 |
3.2 新生代串行收集器
新生代串行收集器采用 复制算法,当JVM在Client模式下运行时,它是默认的垃圾回收器
4 并行收集器
并行收集器是工作在新生代的垃圾收集器,它只是简单地将串行回收器多线程化,并行收集器也是独占式的回收,在收集过程中,应用程序会全部暂停
并行收集器使用多线程进行垃圾回收,在并发能力比较强的系统中,它产生的停顿时间要短于串行回收器。
key value | 描述 |
---|---|
-XX:+UseParNewGC | 新生代使用并行收集器,老年代使用串行收集器 |
-XX:+UseConcMarkSweepGC | 新生代使用并行收集器 老年代使用 CMS |
并行收集器工作时的线程数量可以使用 -XX:ParallelGCThreads 参数指定
在默认情况下,CUP数量小于8个时,ParalleGCThreads的值等于 CPU数值,当CPU数量大于8时 ParalleGCThreads的值等于 3+5*(cpu个数)/8
4.1 新生代并行回收收集器(Parallel Scavenge)
新生代并行回收器使用复制算法,它注重系统的吞吐量
key value | 描述 |
---|---|
-XX:+UseParallelGC | 新生代使用并行收集器,老年代使用串行收集器 |
-XX:+UseParallelOldGC | 新生代老年代都使用并行回收器 |
key value | 描述 |
---|---|
-XX:+MaxGCPauseMillis | 设置最大垃圾收集停顿时间,它的值是一个大于0的整数 |
-XX:+GCTimeRatio | 设置吞吐量大小 ,它的值是一个 0-100之间的整数 |
-XX:+UseAdaptiveSizePolicy | 打开自适应CG策略 |
MaxGCPauseMillis,设置最大垃圾收集停顿时间,收集器在工作时,会调整Java堆大小或者其他的一些参数,尽可能的把停顿的时间控制在MaxGCPauseMillis以内
GCTimeRatio用来设置吞吐量大小 ,它的值是一个 0-100之间的整数,设置GCTimeRatio的值为n,那么系统将花费不超过 1/(1+n)的时间用于垃圾回收
4.2 老年代并行回收收集器(Parallel Scavenge)
老年代并行回收收集器使用 标记-压缩 算法
5 CMS 收集器
CMS是(Concurrent MarkSweep)的缩写,CMS收集器是一种以获取最短回收停顿时间为目标的收集器
CMS采用的基础算法是:标记—清除
CMS收集器执行的过程包括以下几个阶段
key value | 描述 |
---|---|
初始标记 | 在这个阶段,需要虚拟机停顿正在执行的任务,官方的叫法STW(Stop The Word)。这个过程从垃圾回收的"根对象"开始,只扫描到能够和"根对象"直接关联的对象,并作标记。所以这个过程虽然暂停了整个JVM,但是很快就完成了。 |
并发标记 | 这个阶段紧随初始标记阶段,在初始标记的基础上继续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感受到停顿。 |
并发预清理 | 并发预清理阶段仍然是并发的。在这个阶段,虚拟机查找在执行并发标记阶段新进入老年代的对象(可能会有一些对象从新生代晋升到老年代, 或者有一些对象被分配到老年代)。通过重新扫描,减少下一个阶段"重新标记"的工作,因为下一个阶段会Stop The World。 |
重新标记 | 这个阶段会暂停虚拟机,收集器线程扫描在CMS堆中剩余的对象。扫描从"跟对象"开始向下追溯,并处理对象关联。 |
并发清理 | 清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。 |
并发重置 | 这个阶段,重置CMS收集器的数据结构,等待下一次垃圾回收。 |
其中初始标记 重新标记阶段是串行机制,独占程序,其他阶段是并行机制,在CMS执行的时候对应用程序吞量将造成一定影响。
CMS默认启动的线程数是 (ParallelCMSThreads+3)/4 ParallelGCThreads 是新生代并行收集器的线程数,当然也可以通过-XX:ParallelCMSThreads参数手动设定CMS的线程数量
CMS收集器不是独占式的回收器,在CMS执行过程中,应用程序在不断的进行工作,同时产生了垃圾,这些新产生的垃圾是无法同时被回收的,故在CMS回收过程中,还应该确保应用程序有足够的内存使用,CMS收集器不会在堆内存饱和才进行垃圾回收,而是当堆内存使用率达到某一阈值时,便开始进行回收。
-XX:CMSInitiatingOccupancyFraction 可以来配制这个阈值,默认的是 68,也就是当老年代的空间使用率达到 68%时,会执行一次GC 。
如果应用程序的内存使用率增长的很快,在CMS的执行过程中,已经出现了内存不足的情况,那么 CMS回收就会失败,JVM将启动老年代串行收集器进行垃圾回收,这样,应用程序就会完全中断,直到垃圾收集完成。
CMS 是基于 标记 - 清除 算法 ,在CMS执行过程中,会产生大量的垃圾碎片,-XX:+UseCMSCompactAtFullCollection 开关可以使CMS在垃圾收集完后,进行一次内存碎片整理,内存碎片整理不是并发进行的,-XX:CMSFullGCsBeforeCompaction 参数可设定进行多少次CMS回收后,进行一次内存压缩
6 G1 收集器
G1是目前最新的垃圾回收器
G1是基于 标记-压缩算法,在执行过程中不会产生空间碎片
G1 吸取了增量收集优点,把整个堆划分为一个一个等大小的区域(region)。内存的回收和划分都以region为单位;同时,他也吸取了CMS的特点,把这个垃圾回收过程分为几个阶段,分散一个垃圾回收过程;而且,G1也认同分代垃圾回收的思想,认为不同对象的生命周期不同,可以采取不同收集方式,因此,它也支持分代的垃圾回收。为了达到对回收时间的可预计性,G1在扫描了region以后,对其中的活跃对象的大小进行排序,首先会收集那些活跃对象小的region,以便快速回收空间(要复制的活跃对象少了),因为活跃对象小,里面可以认为多数都是垃圾,所以这种方式被称为Garbage First(G1)的垃圾回收算法,即:垃圾优先的回收
key | 描述 |
---|---|
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC | 启用G1垃圾回收器 |
-XX:MaxGCPauseMillis=50 | 设置G1回收器的目标停顿时间 |
-XX:CGPauseIntervalMillis=20 |
6.1 G1 收集器回收过程
7 堆分配参数总结
• -Xms:设置Java应用程序启动的初始堆大小,一般设置成和-Xmx一样可以减少minor GC次数
• -Xmx:设置java应用程序能获得的最大堆大小,设置太小会增加GC次数,太大会增加GC时间
• -Xss:设置线程栈的大小,与支持的线程数相关 这个就要依据你的程序,看一个线程 大约需要占用多少内存,可能会有多少线程同时运行等。一般不易设置超过1M
• -XX:MinHeapFreeRatio:设置堆空间的最小空闲比例。当堆空间的空闲内存小于这个数值时,JVM变回扩展空间
• -XX:MaxHeapFreeRatio:置堆空间的最大空闲比例。当堆空间的空闲内存大于这个数值时,JVM变回扩展空间
• -Xmn:Sun官方推荐配置为整个堆的3/8
• -XX:NewSize:设置新生代的大小
• -XX:NewRatio:设置老年代和新生代的比例 等于老年代大小/新生代大小
• -XX:SurviorRatio:设置新生代中eden区与survivior区的比例
• -XX:PermSize:设置永久区的初始值 默认是物理内存的1/64
• -XX:MaxPermSize:设置最大的永久区大小 默认是物理内存的1/4
• -XX:TargetSurvivorRatio :设置survivior区的可使用率,当survivior区的空间使用率达到这个数值时,会将对象送入老年代
• -XX:+DisableExplicitGC:禁用显式GC
• 一般Xms、Xmx设置相同,PermSize、MaxPermSize设置相同,这样可以避免伸缩堆大小带来的性能损耗
8 与串行回收器相关的参数
• -XX:+UseSerialGC 在新生代和老年代使用串行收集器
• -XX:PretenureSizeThreshold 设置大对象直接进入老年代的阀值,当对象超过这个值时,将直接在老年代分配,这个参数只对串行收集器有效
• -XX:MaxTenuringThreshold 设置对象进入老年代的年龄的最大值,每一次minorGC后 对象的年龄就+1,任何大于这个年龄的对象,一定会进入老年代,默认是15
9 与并行GC相关的参数
• -XX:+UseParNewGC :在新生代使用并行收集器
• -XX:+UseParallelOldGC:老年代使用并行回收收集器
• -XX:ParallelGCThreads:设置用于垃圾回收的线程数,通常情况下可以和CPU数量相等。但在CPU数量比较多的情况下,设置相对较小
• -XX:MaxGCPauserMillis 设置最大垃圾收集停顿时间。他的值是一个大于0的整数,在收集器工作时,会调整JAVA堆大小或则其他一些参数,尽可能地把停顿时间控制在MaxGCPauseMillls内
• -XX:GCTimeRatio:设置吞吐量的大小,它的值是一个0到100的整数,系统花费不超过1/(1+n)的时间用于垃圾收集,默认99
• -XX:+UseAdaptiveSizePolicy 自适应GC策略
10 与CMS回收器相关的参数
• 启用CMS:-XX:+UseConcMarkSweepGC。 • CMS默认启动的回收线程数目是 (ParallelGCThreads + 3)/4) ,如果你需要明确设定,可以通过-XX:ParallelCMSThreads=20来设定,其中ParallelGCThreads是年轻代的并行收集线程数• CMS是不会整理堆碎片的,因此为了防止堆碎片引起full gc,通过会开启CMS阶段进行合并碎片选项:-XX:+UseCMSCompactAtFullCollection,开启这个选项一定程度上会影响性能,
• 为了减少第二次暂停的时间,开启并行remark: -XX:+CMSParallelRemarkEnabled。如果remark还是过长的话,可以开启-XX:+CMSScavengeBeforeRemark选项,强制remark之前开始一次minor gc,减少remark的暂停时间,但是在remark之后也将立即开始又一次minor gc。• 为了避免Perm区满引起的full gc,建议开启CMS回收Perm区选项:
+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled• 默认CMS是在tenured generation沾满68%的时候开始进行CMS收集,如果你的年老代增长不是那么快,并且希望降低CMS次数的话,可以适当调高此值:
-XX:CMSInitiatingOccupancyFraction=80
这里修改成80%沾满的时候才开始CMS回收。• 年轻代的并行收集线程数默认是(cpu <= 8) ? cpu : 3 + ((cpu * 5) / 8),如果你希望降低这个线程数,可以通过-XX:ParallelGCThreads= N 来调整。
Java中的垃圾回收器的类型概述 《对Java的分析总结》(六)相关推荐
- Java中七大垃圾回收器
在Java中,垃圾回收是JVM最常见的工作,也是保证系统能稳定运行的保障之一,常见的垃圾回收算法有两种:分代回收和分区回收,他们各有优缺.当然回收垃圾不可能空手套白狼,所以下面就介绍一下七种垃圾回收器 ...
- java中数值023是什么类型_【Java 教程(原创)】023.参数传值——引用类型参数的传值...
马上注册,结交更多好友,享用更多功能^_^ 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 本帖最后由 零度非安全 于 2017-3-12 14:03 编辑 点击图片穿越到 索引帖,听说有惊喜 ...
- java中数组属于哪种类型_在Java中,关于数组描述正确的是
[单选题]"真比美重要,美更多的是一种诱惑"是()的观点. [判断题]超星客户端整合了强大的功能,以供老师和同学们使用. [单选题]成本会计的最基本职能是 ( ) [单选题]< ...
- java SE 费用_Java SE 6中的垃圾回收器G1收费是虚惊一场
[51CTO快译]在Sun宣布Java SE 6 update 14版本中的垃圾回收器G1将收费之后,引起了Java社区相当大的反响.之后不久的6月5日,有一个细心的匿名读者发表了这样一个帖子: &q ...
- 垃圾回收器(简单概述)
垃圾回收器(简单概述) GC分类与性能指标 垃圾回收器概述 垃圾收集器没有在规范中进行过多的规定,可以由不同厂商.不同版本的JVM来实现. 由于JDK的版本处于高速迭代过程中,因此Java发展至今衍生 ...
- Java中的垃圾回收与对象生命周期
转载自 Java中的垃圾回收与对象生命周期 1. 垃圾回收 垃圾回收是Java程序设计中内存管理的核心概念,JVM的内存管理机制被称为垃圾回收机制. 一个对象创建后被放置在JVM的堆内存中,当永远 ...
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- Java中IO流,输入输出流概述与总结(转载自别先生文章)
Java中IO流,输入输出流概述与总结 总结的很粗糙,以后时间富裕了好好修改一下. 1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中.其中, 所有输入流类都 ...
- JAVA中的八种基本类型
一.JAVA中的八种基本类型 1.数字类型(6种) ①byte: 占的位数:byte数据类型占八位: 最小值为:-128(-2^7): 最大值为:127(2^7-1): 默认值为:0: 作 ...
最新文章
- java模拟使用接口,关于java:模拟一个类与模拟它的接口
- mysql数据库导入到excel表格数据_[转载]将EXCEL表格中的数据导入mysql数据库表中(两种方法)...
- 【预留】Apache Doris 0.12 官方中文文档学习
- python设置随机数种子为12_Python标准库12 数学与随机数 (math包,random包)(转载)...
- 磁盘文件排序-编程珠玑
- python里 t_python中的“.T”操作
- ASP.NET MVC Framework体验(1):从一个简单实例开始(转)
- linux之压缩文件,查看压缩文件,解压文件的操作命令
- 蓝宝石rx470d原版bios_狼神矿卡烤机89°C!强刷蓝宝石RX570超白金显卡BIOS降温75°教程...
- msvcr71.dll控件常规安装
- mysql中.myd文件_MySQL中找不到.myd文件的有关问题
- 嵌入式系统开发-麦子学院(14)- uboot详解(1)
- Coursera Algorithm Ⅱ week4 编程作业 Boggle
- 运行SSD-TensorFlow报错:tensorflow.python.framework.errors_impl.NotFoundError:
- 19种分布式系统设计模式
- Houdini 过程化地形系统(二):基于UE4的FC5植被系统(1)
- Rethinking Image Aesthetics Assessment:Models,Datasets and Benchmarks
- 一份曝光文件透露解放军核武库:谁也不敢惹中国
- 关于AL3201的学习
- 怎么设置360主页的html,怎么使用360安全卫士设置浏览器主页