JVM系列笔记目录
- 虚拟机的根底概念
- class文件构造
- class文件加载过程
- jvm内存模型
- JVM罕用指令
- GC与调优
GC基础知识
什么是垃圾
没有任何援用指向的一个对象或多个对象(循环援用)
如何找到垃圾
- 援用计数(ReferenceCount),毛病:无奈解决循环援用
- 根可达算法(RootSearching),从根开始查找,找到对象是有用的,找不到的对象为垃圾。
什么是根? 留神联合上一篇博客 JVM系列【5】JVM罕用指令-运行时数据区进行了解。
- 线程栈变量 JVM Stack、native method stack
- 动态变量 static refercences in method area、Clazz
- 常量池 runtime cosntant pool
- JNI指针 c/c++ 指针
常见的垃圾回收算法
- 标记革除(mark sweep)
毛病:地位不间断,产生碎片,效率偏低(须要进行两遍扫描)
实用状况:算法绝对简略,实用于存活对象比拟多的状况
- 拷贝算法 (copying)
阐明:没有碎片,节约空间,复制挪动对象,须要调整对象援用
实用状况:实用于存活对象较少的状况 只扫描一次
- 标记压缩(mark compact)
阐明:没有碎片,效率偏低(两遍扫描,指针须要调整)
- 标记革除(mark sweep)
JVM堆内存分代模型(用于分代垃圾回收算法)
堆内存分代模型是局部垃圾回收器应用的模型,除Epsilon ZGC Shenandoah 之外的GC都应用逻辑分代模型,然而G1 是逻辑分代 物理不分代,除此之外都是逻辑分代 而且物理分代。
分代模型中,分新生代和老年代,比例是1:2
- 新生代 = Eden区+ 2个survivor区
YGC回收后,大多数的对象会被回收,活着的进入s0;
再次YGC,活着的对象eden+s0 进入s1;
再次YGC,活着的对象eden+s1 进入s0;
年龄足够进入老年代,个别垃圾回收器是15,CMS是6;为什么个别垃圾回收器分代年龄是15?参考下 JVM系列【4】内存模型-对象头的内容有哪些,对象头中4位标识GC年龄,所以最大的年龄是
2^4 -1 = 15
;s 区装不下,间接进入老年代。
- 老年代: 寄存一些"固执对象",老年代满了或是调配不下了会触发FCG。
- 永恒代(Permanent Generation,JDK1.7以前)/元数据区(MetaSpace,JDK1.8当前):寄存的是Class文件构造,永恒代必须指定大小限度 ,元数据能够设置也能够不设置,无下限(受限于物理内存),字符串常量在1.7以前寄存在永恒代,1.8当前寄存在堆中。
- 新生代 = Eden区+ 2个survivor区
垃圾回收类型和对象调配过程
- 垃圾回收类型
上一个点解释了堆内存分代模型,这里对立下概念:MinorGC=YGC指的是新生代即Y区的垃圾回收,MajorGC=FGC指的是老年代调配不下或是满了产生的GC,包含新生代和老年代。
- 对象如何调配
在之前的博客中 JVM系列【4】内存模型-new Object()面试6连问-对象如何调配,简略提过这一点。
- 垃圾回收类型
对照流程图,调配过程:
> 1. new对象后优先在栈上调配,栈上调配的对象`pop`后就隐没; > 2. 是否是大对象(Y区调配不下的对象)?是就调配到O区,O区产生FGC后回收 > 3. 不是大对象,优先调配TLAB(Thread Local Allocation Buffer线程本地调配缓存)上,调配不下就调配到Eden区 。
理解栈上调配、TLAB、调配担保机制和升代
- 哪些对象栈上调配?
线程公有对象 、无逃逸对象即来到代码块就没有援用的对象、反对标量替换的对象,如类中变量能够用根本变量替换。
- 线程本地调配Thread Local Allocation Buffer
独占eden空间,默认1%;多线程时候不必竞争eden就能够申请空间,提高效率;可调配小对象 - 调配担保机制
在新生代无奈分配内存的时候,把新生代的对象转移到老生代,而后把新对象放入凌空的新生代。参考
- 对象何时进入老年代?
超过MaxTenuringThreshold指定的次数;
依据动静年龄计算进入老年代,Survivor空间中年龄从小到大的对象进行累加,当退出某个年龄段后,累加和超过survivor区域*TargetSurvivorRatio(默认50%)的时候,就从这个年龄段往上的年龄的对象进行降职到老年代。参考
- 哪些对象栈上调配?
常见的垃圾回收器
常见的垃圾回收器有Serial/SerialOld、ParallelScavenge/ParallelOld、ParNew/CMS、G1、ZGC、Shenandoah、Epsilon。Serial/SerialOld、ParallelScavenge/ParallelOld、ParNew/CMS是分代的垃圾回收器,G1是逻辑上分代物理上不分代,ZGC和Shenandoah是不分代,Epsilon是JDK调试用的垃圾回收器。
历史:JDK诞生,Serial追寻,为了提供效率诞生PS,为配合CMS,诞生PN,CMS是1.4前期引入的,CMS是里程碑式的GC,然而CMS故障比拟多,因而目前没有任何一个JDK版本默认CMS。
Serial
年老代 串行回收
SerialOld
老年代 串行回收
PS(ParallelScavenge)
年老代 并行回收
PO(ParallelOld)
老年代 并行回收
PN(ParNew)
年老代 增强版PS配合CMS的并行回收。PN 和 PS区别?PN 响应工夫优先;PS吞吐量优先
CMS(ConcurrentMarkSweep)
老年代并发的,垃圾回收和应用程序同时运行,升高STW的工夫(200ms);
CMS问题比拟多,所以当初没有一个版本默认是CMS,只能手工指定;
CMS既然是MarkSweep,就肯定会有碎片化的问题,碎片达到肯定水平,CMS的老年代调配对象调配不下的时候,应用SerialOld 进行老年代回收,STW无法忍受;
- 如何解决碎片化:设定
-XX:+UseCMSCompactAtFullCollection
默认开启;设定-XX:CMSFullGCsBeforeCompaction
,默认为0 指通过多少次FGC才进行压缩。 - 浮动垃圾问题解决?升高触发CMS的阈值,放弃老年代有足够的空间;参数
-XX:CMSInitiatingOccupancyFraction
指定应用CMS时老年代应用了指定阈值的内存后触发FGC,倡议68-92%
应用的算法:三色标记+Increamental Update
- 如何解决碎片化:设定
G1
STW能够达到10ms
算法:三色标记+SATB
ZGC
STW号称能够达到1ms
算法:色彩指针ColoredPointers + LoadBarrier
Shenandaoh
算法:ColoredPointers + WriteBarrier
垃圾回收器和内存大小的关系
Serial 几十兆
PS 上百兆-几个G
CMS 20G左右
G1 上百G
ZGC 4T-16T(JDK13能够反对)
常识分享,转载请注明出处。学无先后,达者为先!