jvm

JVM学习8·判断对象的存活

2022-01-20  本文已影响0人  那钱有着落吗

当一个对象没有被任何对象引用,就证明这个对象没有用,那么成为了被回收对象了。

判断对象是否是垃圾的方法有两种:引用计数法、可达性分析

1.对象回收

1.1引用计数法算法

引用计数法就如图中所述,如果有对象引用了对象,则这个对象的引用计数为1,如果没有则为0,但是有一个问题就是,当两个对象互相引用时候,而没有别的对象引用他们,是不是就证明这两个对象其实都是无用的呢?

1.2可达性分析算法(根可达)


来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为 引用链(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。
作为 GC Roots 的对象包括下面几种(重点是前面 4 种):

2.Class回收

Class 要被回收,条件比较苛刻,必须同时满足以下的条件(仅仅是可以,不代表必然,因为还有一些参数可以进行控制):

3.Finalize 方法

即使通过可达性分析判断不可达的对象,也不是“非死不可”,它还会处于“缓刑”阶段,真正要宣告一个对象死亡,需要经过两次标记过程,一次是 没有找到与 GCRoots 的引用链,它将被第一次标记。随后进行一次筛选(如果对象覆盖了 finalize),我们可以在 finalize 中去拯救。

4.引用关系

4.1强引用

一般的 Object obj = new Object() ,就属于强引用。在任何情况下,只有有强引用关联(与根可达)还在,垃圾回收器就永远不会回收掉被引用的对象,即便是JVM报错OOM也不会回收强引用的数据。

4.2软引用

一些有用但是并非必需,用软引用关联的对象,系统将要发生内存溢出(OuyOfMemory)之前,这些对象就会被回收(如果这次回收后还是没有足够的 空间,才会抛出内存溢出)。参见代码:
VM 参数 -Xms10m -Xmx10m -XX:+PrintGC


可以看到这个软引用即使执行垃圾回收,或者这个类是有一个实例,也就是只有一个软引用,然后进行一次gc也不会被垃圾回收,只有当内存不够,即将报错OOM的时候才会把软引用的数据给垃圾回收掉。

例如,一个程序用来处理用户提供的图片。如果将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些使用较少的图片浪费 内存空间,需要手动从内存中移除。如果每次打开图片都从磁盘文件中读取到内存再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都 要访问磁盘,代价巨大。这个时候就可以用软引用构建缓存。

4.3 弱引用

弱引用比软引用更加脆弱,只要发生垃圾回收就会被回收掉。

4.4 虚引用

幽灵引用,最弱(随时会被回收掉) 垃圾回收的时候收到一个通知,就是为了监控垃圾回收器是否正常工作。

上一篇 下一篇

猜你喜欢

热点阅读