JVM

对象存活判定算法

Posted by Clear Blog on May 25, 2017

JVM中虚拟机使用的是可达性算法来判定对象是否存活。 简单的说下可达性算法: 通过一系列的GC Roots对象作为起点向下搜索,搜索的路径称为引用链, 当一个对象到GC Roots没有任何引用链相连时,证明此对象是不可用的。 GC Roots没有引用到对象会被第一次标记,并且进行筛选。 筛选的条件是:此对象是否有必要执行finalize方法,如果对象已经执行过finalize()方法 或对象没有覆盖finalize()方法(即没有在finalize中将自己赋给某个类变量)则会被第二次标记。 两次标记的基本上就等待gc了。每个对象的finalize()只会被调用一次(系统自动调用)。

GC Roots对象指的是以下几种对象: 虚拟机栈中引用的对象 方法区中静态属性引用的变量 方法区中常量引用的对象 本地方法引用的对象 即使对象之间相互引用,只要没有与GC Roots相关联,那么它就会被gc回收。 这就直接推倒了在可达性算法之前引用计数器算法的说法。

引用计数器 给每个对象添加一个计数器,每当被引用则加1,失败则减1.计数器为0时则表示不被引用。

在java中有这种强度的引用,分别是强引用、软引用、弱引用、虚引用。 强度从强到弱。 1.强引用:

1
    Object obj = new Object

只要强引用存在,被引用的对象就不会被回收。

2.软引用: 有用但非必须的对象。在系统将要发生内存溢出异常之前会对象这些对象进行二次回收。jdk1.2提供了 SoftReference来实现软引用。

1
private static HashMap<String,SoftReference<UserDO>> UserCache = null;

3.弱引用 比软引用更弱一些,弱引用对象只能生存到下一次gc,jdk1.2中提供了WeakReference来实现

4.虚引用 最弱的引用关系,为一个对象设置虚引用的唯一目的是能在这个对象被gc时收到一个系统通知。 PhantomReference实现了虚引用。