JVM-对象存活算法和自救

1.引用计数算法

​ 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器减1;任何时刻计数器为0的对象就是不可能再被使用的.

​ 缺点: 它很难解决对象之间相互循环使用的问题,也就导致引用计数法无法通知GC收集器回收他们;

2.可达性分析算法(主流)

​ 基本思路就是通过一系列的称为"GC Roots" 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用联(Reference Chain),当一个对象到GC Roots 没有任何引用链相连(就是GC Roots到这个对象不可达时),则证明此对象是不可用的.

​ 在Java 语言中,可作为GC Roots 的对象包括以下几种:

​ a.虚拟机栈(栈帧中的本地变量表)中引用的对象

​ b.方法区中类静态属性引用的对象

​ c.方法去中常量引用的对象

​ d.本地方法栈中JNI (即一般说的Native方法)引用的对象

3.引用定义

​ 传统(JDK 1.2 之前):如果reference类型的数据中存储的数值代表的是另外一块内存的的起始地址,就称这块内存代表着一个引用.

扫描二维码关注公众号,回复: 11025899 查看本文章

​ 扩充(JDK 1.2 之后):对引用的概念进行了扩充,将引用分为 强引用(Strong Reference), 软引用(Soft Reference), 弱引用(Weak Reference), 虚引用(Phantpom Reference)4种,引用强度依次逐渐减弱,这样就可以实现,当内存空间还足够时,则能保留在内存之中,如果内存空间进行垃圾收集收还是非常紧张,则可以抛弃这些对象

强引用: 指在程序代码中普遍存在,只要强引用还在,就永远不会被垃圾收集器回收掉被引用对象,例如:

​ Object obt = new Object();

软引用:用来描述一些还有用但并非必须的对象.在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果还没有足够的内存,才会抛出内存溢出异常(提供了SoftReference类来实现软引用)

弱引用:用来描述非必须对象的,比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集之前.无论内存是否足够,都会回收掉只被弱引用关联的对象(提供了WeakReference类来实现弱引用)

虚引用:最弱的一种引用关系.一个对象是否被虚引用关联,完全不会对齐生存时间构成影响,也无法通过虚引用来取得一个对象实例(唯一作用就是被虚引用关联的对象在收集器回收时有通知,提供PhantomReference类来实现虚引用)

4.对象的自救

​ 即使是不可达的对象,也并非非死不可,要宣告一个对象死亡,至少要经历两次标记过程

​ 当对象进行可达性分析之后发现没有与GC Roots相连接的引用链;

​ a.第一次筛选和标记:判断条件是对象是否被覆盖finalize()方法或者是否执行finalize()方法;如果没有被覆盖finalize()方法或者已经执行finalize()方法,被视为"没有必要执行直",接被收集器回收死亡;

​ 当对象有必要执行(被finalize()方法覆盖或者未执行finalize()方法),将这个对象放在一个F-Queue 队列之中,并在稍后由虚拟机自动建立,低优先级的Finalizer线程去触发finalize()方法;

​ 并不会等待一个对象执行完毕finalize(),当一个对象执行缓慢或者发生了死循环,就是使得这个队列其他对象处于对待,导致整个内存回收系统崩溃

​ b.**第二次标记:**GC 第二次对F-Queue 中的对象进行小规模的标记,如果对象要在finalize()方法中成功拯救自己,只需与引用链上重新关联上即可(可以把自己this 复制给某个类的变量或者对象的成员变量),此时就会将他移除出"即将回收"的集合;如果没有自救成功就被回收;

发布了22 篇原创文章 · 获赞 5 · 访问量 1049

猜你喜欢

转载自blog.csdn.net/lighter613/article/details/103782380