文章目录
14、垃圾回收概述
一、什么是垃圾
大厂面试题
什么是垃圾?
二、为什么需要GC
三、早期垃圾回收
内存泄漏:无法回收的垃圾过多。(无法回收的垃圾:已经没有用但还是有被引用的对象)
四、Java垃圾回收机制
担忧
应该关心的回收区域
15、垃圾回收相关算法
一、标记阶段:引用计数算法
垃圾标记阶段:对象存活判断
引用计数算法
当对象的引用计数器为0时,直接进行GC。
循环引用
Java并不是选用引用计数算法,而是选可达性分析算法,所以循环链表无法回收在引用计数算法中无法GC,但是在Java中可以GC。
证明Java并不是用引用计数算法的例子
进行了垃圾回收,并且成功回收了这两个对象,如果Java使用的是引用计数算法,那么这两个对象会因为循环调用而无法GC掉,所以Java并不是用引用计数算法。
小结
二、标记阶段:可达性分析算法
可达性分析算法又称根搜索算法、追踪性垃圾收集。
GC Roots
注意
三、对象的finalization机制
finalize()方法是一个空方法。
生存还是死亡?
对象有三种状态:可触及的,可复活的,不可触及的。
- 可触及的:GC Roots的引用链上,不可以GC。
- 可复活的:已经不在GC Roots的引用链上,但是对象重写了finalize()方法,并且方法里可能复活自己。
- 不可触及的:已经不在GC Roots的引用链上,并且没有重写finalize()方法或重写的finalize()方法里没有复活自己。
具体过程
如果是调用finalize()方法后复活的对象,当下一次没在GC Roots引用链上时,会变成不可触及的状态,没有再次复活的机会,因为finalize()方法只能调用一次。
四、MAT与JProfiler的GC Roots溯源
MAT
https://www.eclipse.org/mat/downloads.php
获取dump文件
JProfiler
https://www.ej-technologies.com/products/jprofiler/overview.html
五、清除阶段:标记-清除算法
垃圾清除阶段
标记-清除(Mark-Sweep)算法
标记-清除算法:当内存被耗尽时,STW停止整个程序,然后进行GC。
被标记的对象是不回收的对象(非垃圾对象/可达对象),类似白名单。
标记时,递归遍历使用GC Roots的引用链,给引用链上的所有对象加上标记,被标记对象不进行回收。
缺点
垃圾对象清除也并不是直接删除,而是将清除的对象的地址保存在空闲地址列表里,当下一个新对象创建时,新对象覆盖掉被清除对象。
六、清除阶段:复制算法
复制(Copying)算法
优缺点
这里应该是垃圾对象少的话,复制算法不理想,因为复制算法复制的是存活对象,GC时,如果存活对象很多,那么需要复制的对象就很多,并且还需要把对象的引用地址进行修改,所以复制算法如果垃圾对象少的话就不理想了,视频里的PPT这里写错了。
应用场景
七、清除阶段:标记-压缩(整理)算法
标记-压缩(Mark-Compact)算法
标记-压缩算法又称标记-整理算法。
标记压缩算法是在标记清除算法的基础上增加了对象内存碎片的整理。
标记压缩算法不需要修改存活对象的内存地址,而标记压缩算法需要。
优缺点
指针碰撞
八、小结
三种清除阶段的算法对比
九、分代收集算法
十、增量收集算法、分区算法
增量收集算法
缺点
分区算法
16、垃圾回收相关概念
一、System.gc()的理解
- System.gc()只是提醒JVM垃圾回收器执行GC,但不一定就会马上进行回收。
- Runtime.getRuntime().gc()与System.gc()相同。
- System.runFinalization()是强制调用失去引用的对象的finalization()方法。
二、内存溢出与内存泄漏
内存溢出(OOM)
如果内存不够,会先进行GC,GC后还是没空间才报OOM;如果创建的对象大于堆的最大值,那么并不会进行GC,而是直接报OOM。
内存泄漏(Memory Leak)
内存泄漏可以会出现OOM。
内存泄漏的例子
- 单例模式的类中引用了外部对象,因为单例的类生命周期很长,所以引用的外部对象不能及时的进行GC,从而引发内存泄漏的问题。
- 一些资源因为未调用close()方法进行关闭,从而引发内存泄漏的问题。
三、Stop The World(STW)
因为GC Roots是随时都在变化的,而GC又是根据GC Roots进行可达性分析的,所以需要先暂停所有用户线程,然后再进行垃圾回收。
四、垃圾回收的并行与并发
并发(Concurrent)
并行(Parallel)
并发 vs 并行
垃圾回收的并发与并行
五、安全点与安全区域
安全点(Safe Point)
安全区(Safe Region)
六、引用
这四种引用都是可达的。
强引用(Strong Reference):不回收
软引用(Soft Reference):内存不足即回收
弱引用(Weak Reference):发现即回收
虚引用(Phantom Reference):对象回收跟踪
终结器引用(Final Reference)
下一篇笔记:JVM入门学习笔记——上篇:内存与垃圾回收(17)
学习视频(p134-p168):https://www.bilibili.com/video/BV1PJ411n7xZ?p=134