jvm垃圾回收机制

程序计数器,虚拟机栈,本地方法栈,是线程私有的内存空间,随线程而生,随线程而灭,器内存回收随方法或线程结束而回收,所以垃圾回收对这几个区域不过多的考虑。而java堆和方法区,在运行期间才知道创建那些对象,在其上的回收具有动态性。

(1)对象是否存活

判断算法
1.引用计数法(python使用)

做法:给对象添加一个引用计数器,有地方引用它,计数器加1,引用失效,计数器便减1,但可能存在对象间互相引用,使得其引用计数器都不为零,不能被gc收集器收集。
jvm 的Gc收集器没有采用引用计数法。

2.可达性分析算法(java,c#)
在jvm中有个GC Root Set ,里面有好多个“Gc Roots”对象 。

可作为Gc Roots的对象:

1.虚拟机栈中的引用对象
2.方法区中类静态属性引用的对象
3.方法区中的常量引用的对象
4.本地方法栈中jni引用的对象

算法分析:对于一个对象,若其没有一条可以到达任何Gc Roots的路径,则状态就变为可回收状态。

当一个对象成为可回收状态,不一定意味着其一定会被回收。
在这些状态被标记为可回收的对象中,垃圾收集器会进行一次筛选,

1.当对象没有覆盖finalize方法,或者该方法已被虚拟机调用过,则该对象便真正的被回收。

2.如果判定有必要执行finalize方法,那么将会把对象放到一个F-Queue(finalize queue :释放队列)中,最后将由虚拟机建立一个低优先级的finalizer线程去执行F-Queue中的对象,在此时,若对象让自己与Gc Root关联起来,例如在对象的finalize方法中把自己也就是this赋值给一个一个其他对象的变量类型是当前对象的类型属性(但是如果这个其他对象也是在F-Queue中的就不能完成自救,原因就是这个其他对象本省并不能与gc root相关联),但是因为任何一个对象的finalizer方法只能由虚拟机执行一次,所以任何一个需要被回收的对象,也只能完成一次自救。

原文地址:https://www.cnblogs.com/wangxiaopei/p/8551253.html