您的位置:首页 > Web前端

【JAVA】二 JAVA reference

2016-05-14 03:11 411 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/maguochao_Mark/article/details/51402314

【JAVA】二 JAVA reference

在 jdk 1.2 及其以后,引入了强引用、软引用、弱引用、虚引用这四个概念。

Strong Reference 强引用

java标准的引用方式,表示GC从 Root Set 开始向下扫描,可以找到对应的 Strong Reference。
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

package com.cn.mark.reference;

public class ReferenceTest {

public static void main(String[] args) {
Object o = new Object(); // strong reference
o = null; // clear strong reference
}
}

SoftReference 软引用

它是除strong外,生命周期最长的一种 Reference,只有当JVM Heap中充满Strong References, Full GC无法为heap腾出更多空间而即将抛出OOM时,SoftReferences会被GC回收。

Soft Reference的作用一般是用作不限大小的 cache(无需remove)。
比如将其 Soft Reference 无限地放入 hashmap 中,而不关心hashmap内的对象数量是否会撑爆heap,也不需要手动 remove。
当Heap容量达到OOM触发条件时,VM会自动回收该map里的所有SoftReferences.

ReferenceQueue

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

package com.cn.mark.reference;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;

public class ReferenceTest {

public static void main(String[] args) {
Object o = new Object(); // strong reference

ReferenceQueue rq = new ReferenceQueue();
SoftReference sr = new SoftReference(o, rq);// SoftReference reference
}
}

WeakReference 弱引用

当一个referent,在运行时没有同时被强,软引用,只被Weak Reference自身引用,且Weak Reference从 Root Set 可达,则该referent会被GC回收。

Weak Reference的作用,一般是为referent提供一个被回收的凭据,结合ReferenceQueue可以让程序在第一时间得到referent被回收的事件,从而做一些额外的clean操作。(如果对ReferenceQueue作用和回调感兴趣,可以先看最下面的 ReferenceQueue 简介)

ReferenceQueue

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

package com.cn.mark.reference;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class ReferenceTest {

public static void main(String[] args) {
Object o = new Object(); // strong reference

ReferenceQueue rq = new ReferenceQueue();
WeakReference wr = new WeakReference(o, rq);// WeakReference reference
}
}

PhantomReference 虚引用

一种特殊的Reference,正如他的名字所表达的,幻影引用,他可以像幻影一样附着在referent上。
当GC在遍历引用关系时,如果发现被phantom reference包装过的referent不存在strong, soft,weak引用时(就是除phantom外没有任何引用,幻影的由来),GC会将 phantom reference 放入 Reference queue。以便程序在另一边通过queue的remove/poll方法,感知referent被GC回收的事件。(如果对 ReferenceQueue作用和回调感兴趣,可以先看最下面 ReferenceQueue 简介)

ReferenceQueue

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

作用

虚引用主要用来跟踪对象被垃圾回收器回收的活动。

package com.cn.mark.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

public class ReferenceTest {

public static void main(String[] args) {
Object o = new Object(); // strong reference

ReferenceQueue rq = new ReferenceQueue();
PhantomReference pr = new PhantomReference(o, rq);// PhantomReference reference
}
}

Referent

被包装为 Weak, Soft, Phantom Reference的对象引用称之为 referent。后面的内容会多次提到这个名词。

GC

GC在回收对象前会先调用对象自身的finalize()方法,如果它有实现的话,然后再清掉内存。
Phantom Reference的回调(enqueue)是在对象的finalize后,回收前触发。
WeakReference是在回收后才通知的。

为什么 Phantom Reference 的get总是返回null?

因为phantom reference想做到幻影(除自身外,不跟其他任何引用有关联),所以不允许程序能通过自身的get方法得到referent,而破坏幻影的初衷。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: