jvm_垃圾回收学习笔记_1_如何判断对象已死?(附面试题)
2020-07-19 04:49
585 查看
一、引用计数法
引用计数法顾名思义就是在对象中添加一个引用计数器,每当有其他对象引用它时计数器就+1。大概就是下图这个结构:
在线画图工具:ProcessOn
那么引用计数法有什么优点和缺点呢?我想着就是用一小部分空间换时间吧,这样他的效率高,只要计时器为0就可以回收了。但是仔细想想它也有缺点,就是无法解决循环依赖的问题,如下图所示:
此时A与B互相引用着,就算已经没有其他地方引用着A和B类,但是他们之间互相有引用,垃圾回收器就不能回收它们。
此时我们可以做一个实验来测试一下。
这里用的是jdk14,默认是G1垃圾回收器,打印GC日志的参数是
-XX:+PrintGCDetails,此时可以看到垃圾回收器是回收了这两个对象的(
Pause Full (System.gc()) 1M->0M(8M))。由此可见JVM不是通过引用计数法来判断对象是否已经死翘翘的~
这里笔者也没找到资料说明JVM是从什么版本开始弃用引用计数法的或者根本没有使用,有知道的大神可以在评论区说下~那么JVM到底是怎么判断对象是否已死的呢?这就是要到下面要介绍的可达性分析算法了。
二、可达性分析算法
可达性分析算法就是通过一堆已“GC Roots”的跟对象作为起始节点并且以这些节点开始根据引用关系向下搜索,搜索的过程称为‘引用链’。如果某个对象对GC Roots见没有任何引用关系,则判定改对象死亡。图解如下:
如图。Obj1-Obj4都可以追溯到GC roots对象,所以他们不会被回收;Obj5和Obj6虽然互相引用,但是并没有GC Roots对象引用他们,所以可以判定它们两已经死亡~
三、面试题
1、谈谈在jvm中如何判断一个对象是否死亡
上面已分析,不在重复。
2、如何判断一个常量是否死亡,
此题同
java单例对象会被回收吗?大致相同。在JVM中,判断一个常量是否死亡的条件十分严格,有以下三个条件:
- 该类的所有实例以及其子类实例都已被回收
- 加载该类的类加载器被回收
- 该类的Class对象没有在任何地方被引用,也没有在任何地方通过反射调用该类
只有同时满足以上三个条件的常量才会被回收。所以java单例对象基本上是不会被回收的。
3、什么对象可以作为GC Roots对象?
- 在虚拟机栈中被引用的对象
- 在方法区中类静态属性引用的对象
- 在方法区中常量引用的对象
- 本地方法栈中引用的对象(Native方法)
- Java虚拟机内部的引用,如Class对象,异常对象,类加载器等
- 被同步锁持有的对象
- 反映Java虚拟机内部情况的JMXBean、JVMTi中注册的回答、本地代码缓存等
上面7个是查资料查到的。个人感觉作为普通程序员,记住前六个就好了~
相关文章推荐
- jvm垃圾回收(GC)机制之如何判断对象已死
- jvm垃圾回收机制(二)算法和如何进行判断对象是否回收实例
- jvm_垃圾回收学习笔记_2_垃圾收集算法(附面试题)
- JVM-GC笔记(二)--- 对象如何回收
- JVM学习笔记(1、 基本结构;2、Java代码编译和执行的整个过程3、内存管理和垃圾回收 4、 内存调优 )
- jvm如何判断实例对象是否需要回收
- JVM学习笔记(四):GC算法 && 垃圾回收器
- JVM学习笔记3--垃圾回收
- JavaWeb学习笔记—JVM的垃圾回收机制(转载)
- java 垃圾回收步步深入02----判断对象是否已死
- JVM学习笔记----内存管理和垃圾回收
- GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?
- [转]JVM学习笔记(三)------内存管理和垃圾回收
- java面试题之如何判断一个对象是否应该被回收
- JVM学习笔记(三)------内存管理和垃圾回收
- 【java进阶】java虚拟机垃圾回收详解(一)--判断对象已死
- JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
- JVM学习笔记之内存分配与垃圾回收
- JVM学习笔记之垃圾回收算法
- GC是如何判断一个对象为"垃圾"的?被GC判断为"垃圾"的对象一定会被回收吗?