垃圾回收篇-对象已die吗?

如何判断对象需要回收?

1.引用计数算法
给对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加1,当引用失效时,计数器值就减1,当计数器值为0,就表示这个对象不可能再被使用。
这种方法实现简单,效率也高,有着广泛的应用,但在Java虚拟机里,不可使用这种方法,主要原因就是它很难解决对象之间的相互循环引用的问题。
在这里插入图片描述
上图中,对象A与对象B出现了相互循环引用的情况,如果使用引用计数器算法,那么,对象A与对象B的计数器值肯定>=1,他们就不会被回收,但实际情况,JVM在垃圾回收的时候,会清理掉这两个对象。
2.可达性分析算法
这个算法的基本思想就是通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时(GC Roots到这个对象不可达),则证明此对象是不可用的。
那么GC Roots这个抽象的东西包括哪些东西?
a. 虚拟机栈(栈帧中的局部变量表)中引用的对象
b.方法区中类静态属性引用的对象
c.方法区中常量引用的对象
d.本地方法栈中JNI(就是常说的native方法)引用的对象

这么多内容,要被弄晕了…
在这里插入图片描述
画个图感受一下。
在这里插入图片描述

所以在最上面的那张图中,对象A和对象B是GC Roots不可达的对象,在垃圾回收时就会被回收掉。

不可达就必死?

也并不是,不可达的对象此时只是处于"缓行“阶段,如果宣告一个对象死亡需要经历两个标记阶段。
1.判断对象GC Roots不可达时,做第一次标记,然后进行筛选,筛选过程为看对象是否有覆盖finalize()方法。
没有的话就不执行,有的话就这个对象就被判定为需要执行finalize(),这个对象会被放到一个叫F-Queue队列里(这是啥???我也不知道),后面会有个Finalizer线程去执行它(这又是个啥线程???)
2.在finalize()方法执行过程中是对象逃脱死亡的最后一次机会,GC会将F-Queue队列进行第二次标记,在标记前只要重新与GC Roots引用链上任何一个对象关联即可脱离死亡,相反,队列里其他的对象基本上就要被回收了。


可以发现,对象的死亡和finalize()方法有着很大的关系,自己了解的也少,干脆就把注释看了一遍。
在这里插入图片描述
大概的意思就是,垃圾收集器会调用对象的finalize()来回收对象,不过在执行finalize()方法的时候,不会立即回收,而是确认这个对象不可能再被其他对象引用,才会回收,如果期间有其他对象引用了它,它就可以逃离死亡的命运。
总结一下:
一个对象如果被GC Roots不可达,就会被标记一次,如果这个对象没有重写finalize()方法,就会在GC时被直接回收掉。
如果这个对象的类重写了finalize()方法,在回收的时候就需要先执行finalize()方法,如果在此期间对象有被其他对象引用,就会逃离死亡的命运,否则对象只能被回收掉了。
看了一下重写了finalize()方法的类,包含了一些Socket、File I/O、Zip、Proxy类,再根据注释内容,可以得出,finalize()的用途是在对象被回收前做一些cleanup(清理)动作,包括一些I/O、事务、连接内容,在对象被回收之前中断掉。
值得注意的是,finalized()方法只会执行一次,如果一个对象的类重写了finalize(),且对象在第一次执行finalize()没有被清除掉,那么在第二次回收此对象的时候会直接回收掉,不会再执行finalize()。

方法区的回收

主要包括两个内容,废弃常量和无用的类。
废弃常量回收比较简单,比如一个"abc"字符串在常量池中,系统中没有地方引用它,那么这个字符串就会被回收。
无用的类就很难判定了。
1.该类的所有实例都被回收,即堆里不含有任何该类的对象。
2.加载该类的ClassLoader已经被回收了(人在塔在)。
3.该类的java.lang.Class对象没有在任何地方被引用,无法通过反射访问该类。


其实本人不太喜欢用博客来做笔记,因为每次写完后,就不管了,很少再回去看,再加上博客写多了,就不知道怎么找到写过的博客了,所以,我做笔记是写文档的方式,印象深点,也很清楚在哪个位置。
再者,也不推荐其他的朋友只是通过几篇博客对一个知识点的系统学习,本人学习是通过视频+书籍+笔记来对一个知识点的学习。
视频的话,是看张龙老师的JVM课,虽然100多集有点长,但知识面基本上都覆盖了。
不说那些加油啊,追梦啊,冲啊啥的,咱实际点,要不是因为博客可以给面试加分,都懒得写…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值