签名:但行好事,莫问前程。
文章目录
前言
记录一下JVM的垃圾回收。
一、如何判断对象可以回收
1、引用计数法
引用计数法:当一个对象被其他变量所引用,就让这个对象的引用计数+1;某个变量不再引用这个对象,就让他的引用计数-1。当引用变量的计数为0的时候,它就可以作为一个垃圾被进行回收。
弊端:当有循坏依赖的时候,两个相互依赖的对象即使没有被别的对象引用了都不能当做垃圾被回收。
2、可达性分析算法
可达性分析算法:先要确定根对象(肯定不能被当做垃圾回收的对象),在垃圾回收之前,对堆中所有的对象进行扫描,判断每个对象是不是直接或间接的被根对象所引用,如果是,那么这个对象就不能被当做垃圾进行回收。
哪些对象可以作为根对象:GC Root?
- System Class:系统类,启动器加载的类。
- Native Stack:本地栈,调用操作系统的方法引用的Java类。
- Busy Monitor:正在加锁的对象。
- Thread:活动线程。
3、四种引用
- 强引用:被GC Root 直接引用的对象,比如 new 出来的对象,只要存在强引用,就永远不会被垃圾回收。
- 软引用:发生垃圾回收时,发现内存不够的情况下才回收的对象。
- 弱引用:只要发生垃圾回收时,不管内存是否充足都会被回收的对象。
- 虚引用:必须配合引用队列使用,在虚引用的对象被垃圾回收时,虚引用对象就会被放入引用队列,有一个线程调用虚引用对象的方法去释放直接内存。
- 终结器引用:终结器引用放入引用队列中,线程去调用对象的finallize()方法去释放这个对象占用的内存。
二、垃圾回收算法
1、 标记清除
先标记需要回收的内存地址,再清除操作(速度快,会造成内存碎片)
2、标记整理
先标记需要回收的内存地址,再整理不能回收的地址(速度慢,没有内存碎片)
3、复制
先标记存活的对象(FROM区),再将存活的对象复制到另一个区域(TO),完成之后,交换两个区域的位置。(不会有内存碎片,需要占用双倍的内存空间)
三、分代垃圾回收
1、新生代
新生代又分为三个区域:伊甸园、幸存区FROM、幸存区TO。
- 对象首先分配在伊甸园区域
- 新生代空间不足时,触发 minor gc ,将伊甸园和幸存区FROM存活的对象使用复制算法复制到幸存区TO中,让存活的对象年龄+1,并且交换FROM和TO幸存区的位置
- minor gc 回引发 stop the world (垃圾回收线程执行时,其他用户线程会停止)垃圾回收的过程中,涉及到对象的复制,对象的地址会发生改变
- 当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)
- 当老年代空间也不足时,会先尝试触发 minor gc,如果空间仍不足,会触发 full gc
2、老年代
当对象寿命超过阈值时,会晋升至老年代
四、垃圾回收器
五、垃圾回收调优
总结
博客主要记录了JVM的垃圾回收的常见问题,有啥错误或不足地方请指正,如果对你有所帮助,请一键三连。