对于以下,新生代,老年代不了解的朋友可以看我往期文章:
JVM虚拟机03:什么是GC(垃圾回收机制)?什么是新生代和老年代?内存分代模型
1,根据应用场景选择垃圾回收器(GC):
- GC的演化历史:
- GC是随着内存大小的不断增长而演进的
- 场景:从几兆(M)到几十兆(M)
- Serial :单线程STW垃圾回收 年青代 老年代
- 场景:几十兆—上百兆(1G)
- parallel 并行多线程 (JDK1.8默认垃圾回收器 )
- 场景:几十个G的内存(当增加再多的线程的时候,都已经没有用得时候。)
- Concurrent GC(【CMS,ParNew】,C1,ZGC,Shenandoah)
- 注意:在G1之后,摒弃之前分代内存模型,改为分区算法。
2,Java有多少种垃圾回收机制?
虚线表示可以相互搭配使用
(1) 怎么查看计算机使用什么垃圾回收器(GC)?
win+R;cmd
输入命令:
java -XX:+PrintCommandLineFlags -version
-XX:+UseParallelGC:表示parallel Scavenge和paraller Old 组合
3,Serial
(1)在Serial新生代中:
(2)解释说明:
在新生代中,有多个对象,当执行Serial的时候,其他正在运行线程就会,停止,一直到Serial执行完成,所以是STW(停止世界)
(3)面试:为什么要停下来?
因为Serial是应用于比较小内存中,
a,业务中,内存小,扫描速度很短,业务中1到两秒的卡顿是予许的,可以使用Serial
b,在物理内存中,没有足够的空间支持他,一边回收垃圾,一遍产生新的对象。
(4)在老年代中的Serial Old
同样是单线程,但是它使用的是标记清除或者标记压缩,或者标记清除,过于碎片化而标记压缩
4,parallel( 并行多线程 ,回收)
a,JDK1.8默认使用回收器
b,同样是STWv(stop-the-world)叫停正在运行线程,然后多个线程进行垃圾回收
(1) PS [parallel Scavenge(新生代)]
(2)PO [paraller Old(老年代)]
(3)原理大概如下:
5,Concurrent GC(第三类GC,总共5种)
那么什么是Concurrent GC?
它与之前的(单线程,多线程)的STW 的GC最大不同在于,
它进行垃圾回收的时候不会出现叫一切线程停下来,也就是它能够做到并行
业务线程与回收线程同时执行。
从线程的角度来看:
就是业务线程一边跑,回收线程一边标记回收。
(1)CMS 【( Concurrent Mark Sweep)并发的标记清除】
历史上第一个使用并发中的标记清除,GC机制,
CMS发生在老年代。
与之相对应可以选择在新生代中Serial或者PartNew来进行搭配使用的。
概念:
原文:concurrent mark Sweep
翻译:并发标记清除
原文:a mostly concurrent ,low-pause collector
翻译:大部分并发(清除),少数时候暂停收集
4 phases(四个阶段)【实际上是由七个这里只介绍四个最简单,重要的】
1,initial mark(初始标记)
2,concurrent mark(并发标记)
3,remark(重新标记)
4,concurrent sweep(并发清理)
也就是下图四个阶段:
a,四个阶段
1,initial mark(初始标记)
第一步,root Seach 根对象的搜索root对象标记,也就是我们垃圾回收正常流程。
但是没有顺着一个根节点寻找,被引用的对象。
所以在这一步中,虽然在使用了STM,但是时间非常短,因为根节点比较有限,所以暂停的时间就会比较短
2,concurrent mark(并发标记)
当业务线程开始运行之后,GC线程也会跟随着进行(注意,要保证不遗漏业务线程的话,我们上面root对象标记就起作用了。)
这里是最复杂的:
也是传说中:三色标记算法的用武之地
因为篇幅过长会打乱文章布局,所以可以自行百度,
看我写的这一篇文章:
JVM虚拟机05-什么是三色标记算法?使用在并发标记阶段?CMS针对三色标记漏标怎么解决?CMS天生Bug
异常情况:
但是这样容易造成各种各样情况?
最常见的两种就是:
(1)原本是垃圾,被标注了要回收,但是在业务线程运行之下被引用,那么这个回收标记就要清除
(2)原本不是垃圾,没有被标注回收,后来没有引用了,那么就是要回收垃圾,需要标记清除
3,remark(重新标记)
针对于,上述的可能造成的标记标记异常,
所以我们需要对这一步进行一定的修正
因此需要重新标记
那么问题来了,什么时候才会重新标记呢?
即将清理线程的时候就会重新标记。
------------------------------分割线-------------------------
不知道,看到这里童鞋有没有get到我的点,
第一次标记,是标记大部分,
第二次,也就是本部分“重新标记”是为了进行小部分的修正的。
所以,这里的STW时间也不会很长
4,concurrent sweep(并发清理)
想要完整了解七个阶段请看:
Java之CMS GC的7个阶段
(2)PartNew
a,概念:
原文:a stop the world ,Copying collector which uses multiple GC Threads
翻译:一个STM,使用多线程回收GC Copying回收器
b,他与PS(Parallel Scavenge )有什么不同?
原文:It differ form“Parallel Scavenge” in that it has enhancement that make it useable whit CMS
翻译:他是PS的一个增强版,与老年代的CMS搭配
c,举个例子
原文:
For example ,“ParNew” does the synchronize needed so that it can run during the concurrent phases of CMS。
翻译:
例如,“ParNew”会做需要的同步,以便它可以在 CMS 的并发阶段运行。
截上马老师原图:
(3)G1
备注一:G1采用物理上不分代,逻辑上分代
也就说:G1的内存区域不是固定的E或者O,而是在清理之后会变化的。
备注二:当没有连续区域的时候就,就清除
备注三:G1 其中一个毛病就是YGC(年轻代)会统一回收,STW比较长。所以又有了ZGS来解决这个缺陷。
- G1特点:并发收集
- 压缩空闲空间不会延长GC的暂停时间
- 更易预测的GC暂停时间
- 适用不需要实现很高的吞吐量的场景
(4)ZGS
全称:Zero paused GC
在使用的时候,没有老年代,新生代之分了,将内存分为大大小小多个模块,
当某个模块接近慢了,就会单独清理。
触发GC时间:1000ms
- 设计目标:
- 支持TB级别(4T,据说已经扩展到16T)
- 最大GC停顿10ms
- 内存增大,停顿时间不长
- throughput不超过15%都的影响
- SPECjbb 2015基准测试,128g内存,单次GC停顿最大1.68 ms,平均1.09ms
Region Golang核心
核心算法:Colored Pointer(颜色指针) +Load Barrier(读屏障)
特性:
- Colored Pointers
- LoadBarrier
- 完全不同于CPU中的Load Barrier
- 指的是从堆中加载对象之后,执行一段逻辑
- SingleGeneration
- PageAllocation
- 三种不同的动态页面
- Partial Compaction
- Mostly Concurrent
- LoadBarrier
(5)Shenandoah
由红帽贡献给开源JDK的,在JDK1.1版本中才有
与ZGS类似,不过shenandoah采用了三个屏障
6,第四类GC,Epsilon(JDK1.1)
一个比较佛系垃圾回收器,什么都不做的垃圾回收器,
只是单纯的记录:
(1)第一应用场景:
主要是,开发JVM的开发人员,用来debug用的。
(2)第二应用场景:
Epsilon什么都不做,意味着不去干涉,参与程序的运行,所以运行效率特别高,
也就是说它适用于:
内存:特别大
程序:运行过程中,不会憋爆内存,运行完直接统一回收
一些知识后面再补充