jvm之如何判断对象已经死了,再谈引用,生存还是死亡,回收方法区

一、引用计数算法
通常被认为判断对象是否存货的算法是:为对象增加一个引用计数器,当一个地方引用了该对象时,计数器加1,当引用失效时,计数器减1,当引用计数器为0时,表明该对象永远不会被再使用,可以回收。
但是HotSpot不是使用引用计数算法,因为解决不掉对象之间相互引用的情况。
二、可达性分析算法
基本思想是通过一条“GC Roots”的对象座位起点,从这个节点向下搜索,搜索所经过的的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链链接时,则证明此对象不可打。是可以被回收的对象。
jvm之如何判断对象已经死了,再谈引用,生存还是死亡,回收方法区
三、可回收对象
1.虚拟机栈(栈帧中的本地变量列表)中引用的对象。
2.方法区中静态属性引用的对象。
3.方法区中常量引用的对象。
4.本地方发栈中JNI(Native方法)引用的对象

四、再探引用
1.强引用Strong Reference
对象存在Object obj = new Object()的形式,则说明对象存在强引用,强引用的数据,是不会被回收的。
2.软引用Soft Reference
一些对象还有用,但是不是必须的。该类型的对象,在垃圾回收时,系统将要出现内存溢出时,会对这些对象进行二次回收,如果回收了还是内存不够,则会内存溢出。
3.弱引用Weak Reference
指的是分必须的对象,比软引用更弱一些,。该类型的对象会在生存到下一次垃圾回收之前回收。当下一次垃圾回收发生时,无论内存空间够不够,都必须被回收。

4.虚引用Phantom Reference
又叫幽灵引用或者幻影引用,无法从该类型的对象中获取对象实例。
设置该类型的唯一目的是:这个对象被回收器回收时,会收到一个系统通知。
五、生存还是死亡
通过可达性分析算法得到的不可达的对象,也并不是非死不可的。不可达对象只是暂时保存在缓刑阶段。而一个对象的真正死亡要经历两次标记的过程。
流程图如下:
jvm之如何判断对象已经死了,再谈引用,生存还是死亡,回收方法区
jvm之如何判断对象已经死了,再谈引用,生存还是死亡,回收方法区
六、回收方法区
1.判断方法区中废弃常量的方法:没有任何String对象引用常量池中的“abc”常量,也没有其他地方 引用这个字面量。此时发生的内存回收,而且有必要的话,则“abc”将被清理出常池子。
2.碰断一个无用的类的条件,虚拟机满足一下3个条件,可以对该对象进行回收:
A)该类的素有实例都已被回收,也就是java堆中不存在该类的任何实例。
B)加载该类的ClassLoader已被回收。
C)该类对应的java.lang.Class对象没有任何地方引用,无法在任何地方通过反射访问该类的方法。
3.是否对类进行回收,通过设置参数:-Xnoclassgc
4.查看类的加载和卸载参数:-verbose:class以及-XX:+TraceClassLoading、-XX:+TraceClassUnLoading
5.永久代溢出的可能行:
1)大量使用反射、动态代理、CGLib等。
2)大量动态生成JSP
3)频繁自定义ClassLoader