「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
对象存活的判定
栈上分配的对象因为和线程的生命周期一致所以不存在对象存活的判定,也不涉及垃圾回收。
1.引用计数法
在对象中添加一个引用计数器,每当有引用指向它时计数器+1,当引用失效时就-1;任何对象只要计数器不为0,那么他就不会被回收。 特点:
- 原理简单,效率高
- 存在循环引用问题,无法回收此类对象
在Java领域
引用计数法并没有选择此类型的算法,但是微软的COM技术、Python语言在使用这种方式。
2.可达性分析算法
目前主流的高级语言(例如Java、C#)都是通过
可达性分析算法来确定对象是否可以被回收。此算法的基本思路就是通过一系列的GC Roots对象作为起点,从这个节点向下遍历,形成一个引用链,当一个对象到GC Roots没有任何引用链相连时,那么此对象是无用对象需要回收。比如上图中白色部分的对象,即便对象有引用,但是引用连追溯不到GC Roots。
那么固定可作为GC Roots的对象包括以下几种:
- 虚拟机栈(本地变量表)中引用的对象,栈中使用到的参数、局部变量、临时变量。
- 方法区中类变量(静态变量)引用的对象。
- 方法区中常量引用的对象,比如字符串常量池里的引用。
- 本地方法栈中JNI引用的对象(Native方法)。
- JVM的内部引用(Class对象、异常对象、类加载器)。
- 被同步锁(synchronized)持有的对象。
- 反应JVM内部状况的JMXBean、JVMTI中注册的回调、代码缓存。
- JVM运行时临时性的对象,比如GC跨带引用的对象。