JVM性能调优脑图
2023-02-17 21:19:54 0 举报
AI智能生成
JVM GC
作者其他创作
大纲/内容
垃圾收集器
垃圾收集算法
分代收集算法
将java堆分为新生代和老年代,根据各个年龄代的特点选择合适的垃圾收集算法
标记-复制算法
将内存分为两块,一块使用完后,将还存活的对象复制到两一块,然后将使用的空间一次清理掉
标记-清除算法
分为标记和清除两个阶段
两个问题
效率问题:如果要标记的对象太多,效率不高
空间问题:标记清除后会产生大量不连续的碎片
标记整理算法
标记过程和“标记清除”一样
让存活的对象向内存一端移动,然后清理掉边界以外的内存
垃圾收集器
Serial收集器
jvm命令
-XX:+UseSerialGC
-XX:+UseSerialOldGC
单线程,进行收集工作时必须停止其他所有线程(STW),直到收集结束
优势
相对于其他收集器的单线程,简单高效
Parallel Scavenge收集器
jvm命令
-XX:+UseParallelGC
-XX:+UseParallelOldGC
parallel收集器时serial的多线程版本,
parallel scavenge关注点时吞吐量(高效率的利用CPU)
新生代采用复制算法,老年代采用标记整理算法
JDK8默认的新生代和老年代收集器
ParNew收集器
jvm命令
-XX:+UseParNewGC
和parallel收集器类似
它可以和CMS收集器配合使用
CMS垃圾收集器
jvm命令
-XX:+UseConcMarkSweepGC
核心参数
-XX:+UseConcMarkSweepGC:启用cms
-XX:ConcGCThreads:并发的GC线程数
-XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩整理(减少碎片)
-XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次,默认是0,代表每次FullGC后都会压缩一次
-XX:CMSInitiatingOccupancyFraction: 当老年代使用达到该比例时会触发FullGC(默认是92,这是百分比)
-XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction设定的值),如果不指定,JVM仅在第一次使用设定值,后续则会自动调整
-XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor gc,降低CMS GC标记阶段(也会对年轻代一起做标记,如果在minor gc就干掉了很多对垃圾对象,标记阶段就会减少一些标记时间)时的开销,一般CMS的GC耗时 80%都在标记阶段
-XX:+CMSParallellnitialMarkEnabled:表示在初始标记的时候多线程执行,缩短STW
-XX:+CMSParallelRemarkEnabled:在重新标记的时候多线程执行,缩短STW;
一种以获取最短停顿时间为目标的收集器
回收步骤
初始标记
暂停其他所有线程,并记录下gc root直接能引用的对象,速度很快
并发标记
从gc root的直接关联对象开始遍历整个对象图的过程。
因为用户线程持续运行,可能导致已经标记的对象状态发生变更
重新标记
修正因用户线程运行而导致标记产生变动的对象标记记录
主要用到三色标记里的增量更新算法做重新标记
并发清理
开启用户线程,同时GC线程开始对为标记的区域做清扫
并发重置
重置本次GC过程中的标记数据
优点
并发收集,低停顿
缺点
对CPU资源敏感,会和服务器抢资源
无法处理浮动垃圾。在并发标记和并发清理阶段产生的垃圾,只能到下一次GC时进行清理
使用“标记-清除”算法,会导致收集结束时产生大量的空间碎片
执行过程中的不确定性,会存在上一次垃圾回收还没执行完,然后垃圾回收又被触发的情况
G1收集器
jvm命令
-XX:+UseG1GC
面向服务区的垃圾收集器,主要针对配备了多处理器及大容量内存的机器。以极高概率满足GC停顿时间的要求,同时还具备高吞吐的特征
回收步骤
初始标记
暂停所有其他线程,并记录下gc root能直接引用到的对象,速度很快
并发标记
从gc root的直接关联对象开始遍历整个对象图的过程。
因为用户线程持续运行,可能导致已经标记的对象状态发生变更
重新标记
修正因用户线程运行而导致标记产生变动的对象标记记录
主要用到三色标记里的增量更新算法做重新标记
筛选回收
首先对各个region的回收价值和成本排序,根据用户所期望的GC停顿STW时间来制定回收计划
回收算法
G1不管是年轻代或者是老年代,回收算法主要用的是复制算法,将一个region中的存活对象复制到另一个region中,这样不会像CMS那样回收完因为有很多碎片还要再整理一下。
CMS回收阶段和用户线程并发执行的,G1因为内部算法太复杂暂时没有实现并发回收。到了ZGC和shenandoah就实现了并发回收。
G1垃圾收集分类
YoungGC
YoungGC并不是说现有的Eden区放满了就会马上触发,G1会计算下现在Eden区回收大概要多久时间,如果回收时间远远小于参数 -XX:MaxGCPauseMills 设定的值,那么增加年轻代的region,继续给新对象存放,不会马上做Young GC,直到下一次Eden区放满,G1计算回收时间接近参数 -XX:MaxGCPauseMills 设定的值,那么就会触发Young GC
MixedGC
Full GC
ZGC收集器
一款JDK11中新加入的具有实验性质的低延迟收集器,ZGC可以说源自于是Azul System公司开发的C4(Concurrent Continuously Compacting Collector) 收集器。
ZGC目标
支持TB级的堆
最大GC停顿时间不超过10ms
奠定未来GC特性的基础
最糟糕的情况下吞吐量会降低到15%
内存分布
一款基于region内存分布的,暂时不设分代的,使用了读屏障、颜色指针等技术来实现可并发的标记-整理算法的,以最低延迟为首要目标的垃圾收集器
三类容量
小型region(small region)
容量固定为2MB,用于放置256KB的小对象
中性region(mediun region)
容量固定为32MB,用于放置大于等于256KB但小于4MB的对象
大型region(large region)
容量不固定,可以动态变化,但必须为2MB的整数倍。用于放置4MB或以上的大对象
回收步骤
并发标记
与G1一样,并发标记是遍历对象图做可达性分析的阶段,它的初始标记(Mark Start)和最终标记(Mark End)也会出现短暂的停顿
与G1不同的是, ZGC的标记是在指针上而不是在对象上进行的, 标记阶段会更新颜色指针中的Marked 0、 Marked 1标志位
并发预备重分配
这个阶段需要根据特定的查询条件统计得出本次收集过程要清理哪些Region,将这些Region组成重分配集
并发重分配
重分配是ZGC执行过程中的核心阶段,这个过程要把重分配集中的存活对象复制到新的Region上,并为重分配集中的每个Region维护一个转发表(Forward Table),记录从旧对象到新对象的转向关系
并发重映射(Concurrent Remap)
重映射所做的就是修正整个堆中指向重分配集中旧对象的所有引用,但是ZGC中对象引用存在“自愈”功能,所以这个重映射操作并不是很迫切
颜色指针
Colored Pointers,即颜色指针,如下图所示,ZGC的核心设计之一。以前的垃圾回收器的GC信息都保存在对象头中,而ZGC的GC信息保存在指针中。
读屏障
之前的GC都是采用Write Barrier,这次ZGC采用了完全不同的方案读屏障,这个是ZGC一个非常重要的特性。
底层算法实现
三色标记
使用场景
在并发标记过程中,因为在标记期间应用线程还在运行,对象间的引用可能发生变化,多标和漏标的情况就有可能发生
GCRoot可达性分析遍历对象过程中遇到的对象,按照是否访问过的条件标记为三种颜色
黑色
对象已经被垃圾收集器访问过,且对象所有引用已经扫描过
黑色的对象代表已经扫描过, 它是安全存活的, 如果有其他对象引用指向了黑色对象, 无须重新扫描一遍。 黑色对象不可能直接(不经过灰色对象) 指向某个白色对象
灰色
对象已经被垃圾收集器访问过,但至少有一个引用没有被扫描过
白色
对象尚未被垃圾收集器访问过
显然在可达性分析刚刚开始的阶段, 所有的对象都是白色的, 若在分析结束的阶段, 仍然是白色的对象, 即代表不可达
多标-浮动垃圾
针对并发标记和并发清理开始后产生的新对象,通常的做法是直接全部当成黑色
漏标-读写屏障
漏标会导致被引用的对象被当成垃圾误删除,这是严重bug
解决方案
增量更新
当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次
原始快照
当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次
并发标记时,对漏标的处理方案
CMS:写屏障 + 增量更新
G1,Shenandoah:写屏障 + SATB
ZGC:读屏障
颜色指针
Colored Pointers,即颜色指针,如下图所示,ZGC的核心设计之一。以前的垃圾回收器的GC信息都保存在对象头中,而ZGC的GC信息保存在指针中。
每个对象有一个64位指针
18位:预留给以后使用;
1位:Finalizable标识,此位与并发引用处理有关,它表示这个对象只能通过finalizer才能访问;
1位:Remapped标识,设置此位的值后,对象未指向relocation set中(relocation set表示需要GC的Region集合);
1位:Marked1标识;
1位:Marked0标识,和上面的Marked1都是标记对象用于辅助GC;
42位:对象的地址(所以它可以支持2^42=4T内存)
2个mark标记
GC周期1:使用mark0, 则周期结束所有引用mark标记都会成为01。
GC周期2:使用mark1, 则期待的mark标记10,所有引用都能被重新标记。
颜色指针的三大优势
一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理,这使得理论上只要还有一个空闲Region,ZGC就能完成收集
颜色指针可以大幅减少在垃圾收集过程中内存屏障的使用数量,ZGC只使用了读屏障。
颜色指针具备强大的扩展性,它可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能。
记忆集与卡表
关键词解释
写屏障
读屏障
读取一个应用对象时,发现对象被GC是移动走了,JVM就会加上一个读屏障,屏障就会把读取的指针更新到对象新的地址上,并把堆里的这个指针“修正”到原本的字段里
增量更新
当黑色对象插入新的指向白色对象的引用关系时, 就将这个新插入的引用记录下来, 等并发扫描结束之后, 再将这些记录过的引用关系中的黑色对象为根, 重新扫描一次
原始快照
当灰色对象要删除指向白色对象的引用关系时, 就将这个要删除的引用记录下来, 在并发扫描结束之后, 再将这些记录过的引用关系中的灰色对象为根, 重新扫描一次
NUMA
UMA即Uniform Memory Access Architecture(统一的内存访问结构)
NUMA即Non Uniform Memory Access Architecture(非统一的内存访问结构)
分支主题 1
子主题
分支主题 2
0 条评论
下一页