大纲:
- 虚拟机内存模型
- 判断对象已死
- 四种引用
- 垃圾回收算法
- 垃圾回收策略
- 垃圾回收器
一、虚拟机内存模型
根据 JVM 规范,JVM 运行时区域大致分为 方法区、堆、虚拟机栈、本地方法栈、程序计数器 五个部分。
二、判断对象已死
- 引用计数算法:为每个对象增加一个计数器,被引用一次+1,引用失效-1,引用数==0则回收。优点:简单,高效。缺点:如果2个对象除了相互引用外无其他引用,则无法回收。
- 可达性分析算法:一个对象通过一条引用链能达到gc roots则判定对象有效,否则会被回收。gc roots包括虚拟机栈中引用对象、方法区中类静态属性引用对象、方法区中常量引用的对象、native方法引用的对象。
三、四种引用
- StrongReference-强引用:Object o = new Object();gc不回收,内存满则抛出OutOfMemoryError。
- SoftReference-软引用:gc会在内存不足时回收,可以和ReferenceQueue联合使用,软引用引用对象被回收,虚拟机会把这个软引加到相关引用队列中。
- WeakReference-弱引用:gc只要发现弱引用的对象就回收,可以和ReferenceQueue联合使用,弱引用引用对象被回收,虚拟机会把这个弱引加到相关引用队列中。
- PhantomReference-虚引用 被虚引用引用的对象就和没有引用一样,虚引用必须和ReferenceQueue联合使用,gc回收前,发现对象被虚引用引用,就在回收前把虚引用加到相关队列中。
四、垃圾回收算法
- 标记清除-将垃圾标记后清除,但会造成内存碎片化
- 标记整理-将存活对象移动到一端,清除其他内存,解决了内存碎片化问题,但由于频繁移动内存导致效率低。
- 复制-将内存一分为二,每次使用一半,清理时将存活对象复制到另外一半,然后清理当前一半,但每次只能使用一半内存。
- 分代垃圾回收-虚拟机将堆分为老年代和年轻代,年轻代朝生夕死适合复制算法,老年代存活率高,适合标记清除、标记整理算法。
五、垃圾回收策略
堆内存是虚拟机中主要管理区域,占用内存最大。
Java 堆主要分为2个区域-年轻代与老年代,其中年轻代又分 Eden 区和 Survivor 区,其中 Survivor 区又分 From 和 To 2个区。
Eden-由于98%的对象是朝生夕死,eden在年轻代占据大一些,大多数对象出生在eden区。每次eden满触发minor gc。
Survivor-from,to两块作用相同,当发生minor gc,eden和(from/to)中存活的对象被复制到(to/from)中。
Old-老年代占据着2/3的堆内存空间,major gc和full gc 的时候才会进行清理。老年代中包括:
- 大对象:避免在Survivor中来回复制,避免Survivor装不下。
- 长期存活对象:对象每次经历minor gc年龄+1,16岁后进入老年代。
- 动态对象年龄判定:虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。对应虚拟机参数-XX:TargetSurvivorRatio 目标存活率,默认为50%
六、垃圾回收器
下图为垃圾回收器的常见组合,垃圾回收器分新生代回收器,老年代回收器,全年代回收器(G1)
1.Serial:单线程,每次回收STW
2.ParNew:Serial多线程版本
3.Parallel Scavenge:可以控制吞吐量(工作时间/工作时间+gc时间),默认使用GC自使用策略(动态调整新生代各部分大小),也可以调整两个参数:
- XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间
- XX:GCRatio 直接设置吞吐量的大小
4.Serial Old:Serial老年代版本
5.Parallel Old:ps老年代版本
6.cms:停顿时间短,注重服务端响应速度
cms垃圾回收有4个阶段,采用三色标记的方法进行标记(黑色:本身及子结点全部被垃圾回收器访问过;灰色:本身被访问,子结点未被全部访问;白色:未被访问过)
1.初始标记:stw,对象初始为白色,gcroots为黑色,将gcroots直接引用的对象标记灰色
2.并发标记:根据可达性分析,在用户线程不停止的情况下,扫描灰色及其子结点;同时并发标记期间黑色结点新增的引用关系会被记录下来,因为会出现引用消失问题(某个白色结点本来被灰色结点引用,突然这个引用消失,但被黑色结点重新引用,由于黑色 结点不被再次扫描,所以在并发标记后该对象还是白色)
3.重新标记:stw,扫描并发标记阶段黑色结点新增的引用关系,解决对象消失问题
4.并发清除:并发清除白色标记的对象
cms缺点:
1.并发标记和并发清除占用cpu
2.由于并发,无法清除浮动垃圾,当浮动垃圾产生的速度大于并发清除速度,老年代的空间被占用到一定比例时,需要Serial Old来帮忙进行依次major gc
3.采用标记清除算法,产生内存碎片,碎片严重时,需要Serial Old来帮忙进行依次major gc
7.g1:全年代的垃圾回收器,注重服务端响应速度
g1特点:
1.将堆内存默认分为2048个等大的Region,每个Region可以是年轻代,也可以是老年代,还有可能时大对象,每代不再时一个连续的区域。每个Region有自己的回收价值(垃圾对象比例,预期回收时间与效果)
2.可以设置停顿时间,控制每次垃圾回收的总时长
3.回收时,筛选价值高的Region来回收,由于有停顿时间限制,可分多次回收
4.靠新生代、老年代达到Region的比例来判断是否需要进行回收
5.标记过程与cms一样采用三色标记