Java Reference详解

本文参考了:
http://blog.csdn.net/androidstar_cn/article/details/54710652
http://blog.csdn.net/qq_32347977/article/details/51655521

Reference是java中的引用类,它用来给普通对像进行包装,从而在JVM在GC时,按照引用类型的不同,在回收时采用不同的逻辑。先来看下这个类的继承体系:


image.png

在进行对这些子类进行分析解释之前,我们先来看几个概念:

对象的生命周期
image.png

1.创建阶段(Created)
在创建阶段系统通过下面的几个步骤来完成对象的创建过程

  • 为对象分配存储空间
  • 开始构造对象
  • 从超类到子类对static成员进行初始化
  • 超类成员变量按顺序初始化,递归条用超类的构造方法
  • 子类成员变量按顺序初始化,子类构造方法调用
    一旦对象被创建,并被分派给某些变量赋值,这个对象的状态就切换到了应用阶段。下面通过具体示例看看:
public class GrandParent {

    public GrandParent(){
        super();
        System.out.println("GrandParent 构造函数");
    }

    {
        System.out.println("GrandParent 成员代码块");
    }

    static {
        System.out.println("GrandParent 静态代码块");
    }
}
public class Parent extends GrandParent {


    public Parent() {
        super();
        System.out.println("Parent 构造函数");
    }

    {
        System.out.println("Parent 成员代码块");
    }

    static {
        System.out.println("Parent 静态代码块");
    }


}
public class Child extends Parent {


    public Child() {
        super();
        System.out.println("Child 构造函数");
    }

    {
        System.out.println("Child 成员代码块");
    }

    static {
        System.out.println("Child 静态代码块");
    }


}

child为子类,parent为child的超类,GrandParent为超类的超类,当我们执行

Child child = new Child();

执行顺序为:


image.png

当我们执行

Parent parent = new Parent();

执行顺序为:


image.png

从而证明了一个对象创建阶段的执行顺序。
2.应用阶段(In Use)
对象至少被一个强引用持有着。即上述例子中的child持有new Child()的强引用。
3.不可见阶段(Invisible)

当一个对象处于不可见阶段时,说明程序本身不再持有该对象的任何强引用,虽然这些引用是存在着的。简单说就是程序的执行已经超出了该对象的作用域了。举例来说:
image.png

则在此时称之为count处于不可视阶段。当然这种情况编译器在编译的过程中会直接报错了。
4.不可达阶段(Unreachable)

对象处于不可达阶段是指该对象不再被任何强引用所持有。与"不可见阶段"相比,"不可达阶段"是指程序不再持有该对象的任何强引用,这种情况下,该对象仍可能被JVM等系统下的某些已装载的静态变量或线程或JNI等强引用持有着,这些特殊的强引用被称为"GC root"。存在着这些GC root会导致对象的内存泄露情况,无法被回收。
5.收集阶段(Collected)
当垃圾回收器发现该对象已经处于"不可达阶段"并且垃圾回收起已经对该对象的内存空间重新分配做好准备时,则对象进入了"收集阶段"。如果该对象已经重写了finalize()方法,则会去执行该方法的终端操作。这里要注意尽量不要重载finalize()方法,原因有两点:

  • 会影响JVM的对象分配于回收速度
    在分配该对象时,JVM需要在垃圾回收器上注册该对象,以便在回收时能够执行该重载方法;在该方法执行时需要消耗CPU时间且在执行完该方法后才会重新执行回收操作,即至少需要垃圾回收器对该对象执行两次GC。
  • 可能造成该对象的再次"复活"
    在finalize()方法中,如果有其它的强引用再次持有该对象。则会导致对象的状态由" 收集阶段"又重新变为"应用阶段"。这个已经破坏了Java对象的生命周期进程,且复活的对象不利于后续代码管理。
  • 终结阶段(Finished)
    当对象执行完finalize()方法后处于不可达状态时,则该对象进入终结状态。在该阶段是等待垃圾回收器对该对象空间进行回收。
  • 对象空间重分配阶段(De-allocated)
    垃圾回收器对该对象的所占用的内存空间进行回收或者再分配,则该对象测底消失了,称之为"对象空重新分配阶段"
对象可达性判断

jvm 发生gc时,判断一个对象是否存在引用,都是从根结合引用开始去标识,往往到达一个对象的引用路径会很多,如下图:


image.png

那么垃圾回收时会依据两个原则来判断对象的可达性:
单一路径中,以最弱的引用为准
多路径中,以最强的引用为准
例如Obj4的引用,存在:1>6、2>5、3>4,那么从根对象到Obj4的最强引用为2>5,因为它们都是强引用。如果仅仅村子一个路径对Obj4有引用时,比如Obj4有引用时,比如现在只剩下1>6,那么根对象到Obj4的引用以最弱的为准。是软引用。Obj4就是softly-reachable对象。

强引用(StrongReference)

强引用就是我们平时创建对象,创建数组时的引用。强引用在任何时候都不会被GC回收掉。例如

Parent parent = new Parent();
软引用(SoftReference)

软引用是在系统发生OOM之前才被JVM回收掉。软引用常被用来对于内存敏感的缓存。

弱引用(WeakReference)

一旦JVM执行GC,弱引用就会被回收掉。

(虚引用)PhantomReference

虚引用主要作为其指向referent被回收时的一种通知机制。

总结

通过对SoftReference,WeakReference,PhantomReference,可以看出JDK提供这些类型的reference 主要是用来和GC交互的,根据reference的不同,让JVM采用不同策略来进行对对象的回收(reclaim)。softly-reachable的referent在保证在OutOfMemoryError之前回收对象,weakly-reachable的referent在发生GC时就会被回收,。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容