1.写在前面
前面分享了GC基本原理和调优关键分析,详情可查看:这里
基于该文章,我们了解了,如何找到垃圾,如何使用垃圾回收器清除垃圾。
我们之前已经给出了有 7 种不同的垃圾回收器,大概的讲了一下,这些垃圾回收器的搭配,对应于那个年代(老年代、新生代) 的垃圾回收。
那今天我们继续详细的分享一下:JVM垃圾收集器
这些垃圾回收器,具体的一些原理。
好了,废话不多说,直接上干货。(纯理论比较多,大家伙耐心点看)
哈哈,绝对有收获,没收获的轻点喷!!!^_^
新生代 |
老年代 |
Serial |
Serial Old |
Serial |
CMS |
ParNew |
Serial Old |
ParNew |
CMS |
Parallel Scavenge |
Serial Old |
Parallel Scavenge |
Parallel Old |
G1 |
G1 |
这里先贴一下,常见的垃圾回收器。
2.JVM垃圾收集器
2.1.串行收集器(Serial)
2.1.1 基本概念
使用单线程进行垃圾回收的收集器,每次回收时,串行收集器只有一个工作线程,对于并行能力较弱的计算机来说,串行收集器的专注性和独占性往往有更好的性能表现。
串行收集器可以在新生代和老年代中使用,根据作用于不同的堆空间,分为新生代串行收集器和老年代收集器。
配置参数 -XX:+UseSerialGC :年轻串行(Serial),老年串行(Serial Old)
2.1.2 Serial收集器:年轻串行
Serial收集器是一个新生代收集器,单线程执行,使用复制算法。它在进行垃圾收集时,必须暂停其他所有的工作线程(用户线程)。是JVM Client模式下默认的新生代收集器。对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。
这里说的复制算法,大家伙,还有记得不?
就是我们上一篇说得的三种垃圾清除算法。
哈哈,估计都忘了吧?这里,咋们再回顾一下
- Mark-Sweep 标记清除算法
- Copying 拷贝算法
- Mark-Compact 标记压缩算法
2.1.3 Serial Old收集器:老年串行
这里,解析一下什么是safe point?
挂起线程的点
safepoint可以用来实现让所有Java线程挂起的需求。这是一种 “主动式”(Voluntary Suspension)的实现
safe point指的特定位置主要有:
- 循环的末尾 (防止大循环的时候一直不进入safepoint,而其他线程在等待它进入safepoint)
- 方法返回前
- 调用方法的call之后
- 抛出异常的位置
以上的两种,就是串行的垃圾收集器了,下面继续分析并行的垃圾收集器。
2.2. 并行收集器
2.2.1 Parallel Scavenge收集器
配置参数:-XX:+UseParallelGC
目标是达到一个可控制的吞吐量(Throughput)。
吞吐量 = 运行用户代码时间 /(运行用户代码时间+垃圾收集时间)。
虚拟机总共运行了 100 分钟,其中垃圾收集花掉 1 分钟,那吞吐量就是99%。
特点:
这里,有必要,解析一下什么是并发,什么是并行?
答应我,别再傻傻分不清楚了!
2.2.2 Parallel Old收集器
配置参数:-XX:+UseParallelOldGC
特点:
2.2.3 ParNew收集器
配置参数:-XX:+UseParNewGC
配置参数:-XX😛arallelGCThreads=n 设置并行收集器收集时使用的并行收集线程数。一般最好和计算机的CPU相当
特点:
2.2.4 CMS收集器
配置参数:-XX:+UseConcMarkSweepGC 应用CMS收集器。
尽管CMS收集器采用的是 并发回收(非独占式) ,但是在其初始标记和重新标记这两个阶段中仍然需要执行“Stop-the-World”机制暂停程序中的工作线程,不过暂停时间并不会太长。
因此可以说明 目前所有的垃圾收集器都做不到完全不需要“stop-the-World , 只是尽可能地缩短暂停时间 。
由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的。
另外,由于在垃圾收集阶段用户线程没有中断 ,所以在CMS回收过程中,还应该确保应用程序用户线程有足够的内存可用。
特点:
CMS垃圾回收器:
CMS整个过程比之前的收集器要复杂,整个过程分为 4 个主要阶段,即初始标记阶段、并发标记阶段、重新标记阶段和并发清除阶段。
( 涉及STW的阶段主要是:初始标记 和 重新标记 )
好吧,有点长了,坚持一下,快完了!!!
2.2.5 G1(Garbage-First)收集器
配置参数:-XX:+UseG1Gc 应用G1收集器
配置参数:-XX:MaxGCPauseMillis 指定最大停顿时间
配置参数:-XX😛arallelGCThreads 设置并行回收的线程数量
Garbage-First当今收集器技术发展的最前沿成果之一,G1是一款面向服务端应用的垃圾收集器。大内存,企业配置的垃圾收集器大多都是G1。
特点:
- 并行与并发:充分利用多CPU、多核环境下的硬件优势
- 分代收集:不需要其他收集器配合就能独立管理整个GC堆
- 空间整合:“标记—整理”算法实现的收集器,局部上基于“复制”算法不会产生内存空间碎片
- 可预测的停顿:能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒
G1收集器的运作大致可划分为以下几个步骤:
- 初始标记:标记一下GC Roots能直接关联到的对象,需要停顿线程,但耗时很短
- 并发标记:是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行
- 最终标记:修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录
- 筛选回收:对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划
好了,以上就是并行收集器的描述了。
哈哈,可能有点长,耐心点看吧!!!
总结
在众多的垃圾回收器中,没有最好的,只有最适合应用的回收器,根据应用软件的特性以及硬件平台的特点,选择不同的垃圾回收器,才能有效的提高系统性能。
好了,以上就是我个人的经验的分享了。
个人理解,可能也不够全面,班门弄斧了。
今天就先到这里了,掰掰了!!!^_^
如果觉得有收获的,帮忙点赞、评论、收藏一下呗!!!
声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!