Java Reference & ReferenceQueue一览
Overview
The java.lang.ref package provides more flexible types of references than are otherwise available, permitting limited interaction between the application and the Java Virtual Machine (JVM) garbage collector. It is an important package, central enough to the language for the language designers to give it a name that starts with "java.lang", but it is somewhat special-purpose and not used by a lot of developers. This package was added in J2SE 1.2.
Java has an expressive system of references and allows for special behavior for garbage collection. A normal reference in Java is known as a "strong reference." The java.lang.ref package defines three other types of references — soft, weak, and phantom references. Each type of reference is designed for a specific use.
Reference in JAVA
Base
Strong Reference,强引用,即java标准的引用方式,表示GC从 Root Set 开始向下扫描,可以找到对应的 Strong Reference。
FinalReference 作为 java.lang.ref 里的一个不能被公开访问的类,实际上,FinalReference 代表的正是 Java 中的强引用。
Referent,被包装为 Weak, Soft, Phantom Reference的对象引用称之为 referent。
Soft Reference ,软引用。它是除strong外,生命周期最长的一种 Reference,只有当JVM Heap中充满Strong References,
Full GC无法为heap腾出更多空间而即将抛出OOM时,SoftReferences会被GC回收。
Weak Reference,弱引用。当一个referent,在运行时没有同时被强,软引用,只被Weak Reference自身引用,且Weak Reference
从 Root Set 可达,则该referent会被GC回收。
WR的作用,一般是为referent提供一个被回收的凭据,结合ReferenceQueue可以让程序在第一时间得到referent被回收的事件,
从而做一些额外的clean操作。
Phanton Reference, 是一种特殊的Reference,正如他的名字所表达的,幻影引用,他可以像幻影一样附着在referent上。
当GC在遍历引用关系时,如果发现被phantom reference包装过的referent不存在strong, weak, soft引用时(就是除phantom外
没有任何引用,幻影的由来),GC会将 phantom reference 放入 Reference queue。以便程序在另一边通过queue的remove/poll
方法,感知referent被GC回收的事件。
feature
Soft Reference | Keeps objects alive provided there’s enough memory. | to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key. | After a first gc pass, the JVMdecides it still needs to reclaim more space. | java.lang.ref.SoftReference |
Weak Reference | Keeps objects alive only while they’re in use (reachable) by clients. | Containers that automatically delete objects no longer in use. | After gc determines the object is only weakly reachable | java.lang.ref.WeakReference java.util.WeakHashMap |
Phantom Reference | Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use offinalize()) | Special clean up processing | After finalization. | java.lang.ref.PhantomReference |
important
按理说,Soft Reference 与 Weak Reference都可以用来实现缓存,只是失效策略不同,一个是内存不足时清理,一个是随意清理
另外WeakHashMap并不适用于缓存,详见weakHashMap解析
Overview the relationship between Reference&ReferenceQueue
ReferenceQueue是作为 JVM GC与上层Reference对象管理之间的一个消息传递方式,允许注册一些监听器来获取回收状态
class#java.lang.ref.Reference
reference objects are implemented in close cooperation with the garbage collector
Overview
/* A Reference instance is in one of four possible internal states:
一个Reference实例有以下4种内部状态
*
* Active: Subject to special treatment by the garbage collector. Some
* time after the collector detects that the reachability of the
* referent has changed to the appropriate state, it changes the
* instance's state to either Pending or Inactive, depending upon
* whether or not the instance was registered with a queue when it was
* created. In the former case it also adds the instance to the
* pending-Reference list. Newly-created instances are Active.
* 当垃圾回收器探测到引用的可达性变成某些适合的状态的时候,
* 它会将该内部状态变成Pending或者Inactive,
* 这取决于在实例化这个Reference对象的时候是否传入了ReferenceQueue。
* 如果传入了,那么它同时会将该实例添加到pending-Reference列表中。
* 新创建的引用对象是Active
*
* Pending: An element of the pending-Reference list, waiting to be
* enqueued by the Reference-handler thread. Unregistered instances
* are never in this state.
* 一个在Pend-Reference列表中的元素,正等待着Reference-handler线程将他入队。
* 未注册的实例不会出现在这个状态。
*
* Enqueued: An element of the queue with which the instance was
* registered when it was created. When an instance is removed from
* its ReferenceQueue, it is made Inactive. Unregistered instances are
* never in this state.
* 当一个实例从它的ReferenceQueue中被删除时,它变成Inactive状态。
* 未注册的instance不会
*
* Inactive: Nothing more to do. Once an instance becomes Inactive its
* state will never change again.
* 不会再做任何改变。一旦某个实例变成了Inactive态,它的状态不会再有任何改变。
*
* The state is encoded in the queue and next fields as follows:
*
* Active: queue = ReferenceQueue with which instance is registered, or
* ReferenceQueue.NULL if it was not registered with a queue; next =
* null.
*
* Pending: queue = ReferenceQueue with which instance is registered;
* next = Following instance in queue, or this if at end of list.
*
* Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
* in queue, or this if at end of list.
*
* Inactive: queue = ReferenceQueue.NULL; next = this.
*
* With this scheme the collector need only examine the next field in order
* to determine whether a Reference instance requires special treatment: If
* the next field is null then the instance is active; if it is non-null,
* then the collector should treat the instance normally.
*
* 以这种方式,收集器只需要检查next字段,以决定是否该引用实例应该被特殊处理
* 如果下一个字段是null,说明该实例为active
* 如果不是null,说明回收器应该立刻处理该实例
*
* To ensure that concurrent collector can discover active Reference
* objects without interfering with application threads that may apply
* the enqueue() method to those objects, collectors should link
* discovered objects through the discovered field.
*
* 为了保证并发收集器可以再不受应用程序线程调用enqueue()发放的影响下,发现active reference
* 收集器应该吧已经发现的objects通过discovered 字段表示。
*
*/
Inner Field 非static
T referent
Treated specially by GC
是该引用实例真正指向的对象,为了避免和reference同名,名字叫做referent
ReferenceQueue<? super T> queue
引用队列,通知队列(使用方法具体见后文)
Reference next
链表指针,是GC里面的pending list
Reference<T> discovered
used by VM
Global Field ,static
一个空对象,用于锁同步
/* Object used to synchronize with the garbage collector. The collector
* must acquire this lock at the beginning of each collection cycle. It is
* therefore critical that any code holding this lock complete as quickly
* as possible, allocate no new objects, and avoid calling user code.
* 这是垃圾回收器用来同步的对象。在垃圾回收周期之前,回收器需要获取这个锁。
* 因此,任何持有该锁的对象应该尽快执行完,尽量不要分配新对象,避免调用用户代码
*/
Reference<T> pending
所谓的pending链表,依赖于reference的next指针实现,大部分对于该链表的操作都是通过vm执行
ReferenceHandler#Class
implement Runable
监听(wait/notify)pending链表,通过将pending链表的元素enque来实现监视器模式,以便回调各个reference注
册的queue上面的的监听者(调用remove或者poll方法)
for (;;) { Reference r;
synchronized (lock) {
if (pending != null) {
//删除pending列表的该对象
r = pending;
Reference rn = r.next;
pending = (rn == r) ? null : rn;
r.next = r;
} else {
try {
lock.wait(); //该wait由VM来notify
} catch (InterruptedException x) { }
continue;
}
} // Fast path for cleaners
// 钩子
if (r instanceof Cleaner) {
((Cleaner)r).clean();
continue;
} ReferenceQueue q = r.queue;
//将该对象入队
//加入ReferenceQueue中的链表中,见下文
if (q != ReferenceQueue.NULL) q.enqueue(r);
}
static块
启动ReferenceHandler 设置为最高优先级并且为守护进程
Interface
Reference(T referent)
默认构造器
Reference(T referent, ReferenceQueue<? super T> queue)
带有ReferenceQueue的构造器
T get()
获取该referent
void clear()
清空
boolean isEnqueued()
是否入队,根据queue和next指针来判断
boolean enqueue()
入队方法,VM不会调用该方法,暂时不知道谁来调用
class#java.lang.ref.ReferenceQueue
Overview
Reference queues, to which registered reference objects are appended by the
garbage collector after the appropriate reachability changes are detected.
引用队列,将Reference Object注册到该队列上,使得当垃圾回收器改变其到某些状态的时候能够被探测到。
总之,这是一个观察引用对象回收的东西
通过wait/notify实现的阻塞和非阻塞调用~
该操作涉及一些并发知识哦~
Inner Field
//队列头
volatile Reference<? extends T> head = null;
//队列长度
long queueLength = 0;
Interface
enqueue
Called only by Reference Class
调用入队操作,删除元素的对该队列的引用,将元素插入头,增加长度,lock.notify
remove
阻塞调用(lock.wait),获取一个元素。
poll
非阻塞调用。
基于Reference和ReferenceQueue实现的WeakHashMap
REFERENCE
Java Reference & ReferenceQueue一览的更多相关文章
- Java Reference简要概述
@(Java)[Reference] Java Reference简要概述 Reference对象封装了其它对象的引用,可以和普通的对象一样操作. Java提供了四种不同类型的引用,引用级别从高到低分 ...
- Java Reference 源码分析
@(Java)[Reference] Java Reference 源码分析 Reference对象封装了其它对象的引用,可以和普通的对象一样操作,在一定的限制条件下,支持和垃圾收集器的交互.即可以使 ...
- java Reference
相关讲解,参考: Java Reference 源码分析 Java Reference详解 Reference: // 名称说明下:Reference指代引用对象本身,Referent指代被引用对象 ...
- Java Reference核心原理分析
本文转载自Java Reference核心原理分析 导语 带着问题,看源码针对性会更强一点.印象会更深刻.并且效果也会更好.所以我先卖个关子,提两个问题(没准下次跳槽时就被问到). 我们可以用Byte ...
- Java面试题一览
Java面试题一览
- java Reference(摘录)
Java中的Reference对象和GC是紧密联系在一起的,Reference的实现也是和GC相关的. 强引用 强引用是Java中使用最普遍的引用,我们经常使用的Object o = new Obje ...
- Java reference的种类及使用场景
Java 中一共有 4 种类型的引用 : StrongReference. SoftReference. WeakReference 以及 PhantomReference (传说中的幽灵引用).这 ...
- WeakReference Reference ReferenceQueue
public class WeakReference<T> extends Reference<T> { public WeakReference(T referent) { ...
- Implementing the skip list data structure in java --reference
reference:http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Map/skip-list-impl.html The link ...
随机推荐
- Java 调用PHP的Web Service(三)
usoap是PHP环境中的开源soap工具,算是用得比较多的一个工具了. 在utf-8环境中,nusoap可以工作得很好.但是当用于中文环境中时,nusoap经常会出现一些让人不得其解的问题. 最近一 ...
- 转载 Linux top命令详解
TOP命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况. TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止 ...
- linux下redis的安装及配置启动
linux下redis的安装及配置启动 标签: redisnosql 2014-10-24 14:04 19732人阅读 评论(0) 收藏 举报 分类: 数据与性能(41) wget http:/ ...
- linux下部署tomcat服务器之安装tomcat
下载tomcat压缩包 apache-tomcat-7.0.82.tar.gz 在把包放到linux 的softwore文件夹下 自己选择文件夹 tar -zxvf apache-tomcat-7. ...
- 常量池之字符串常量池String.intern()
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...
- maven安装之后,或者升级之后遇到的问题:could not find or load main class org.codehaus.plexus.class.....
从maven2升级到maven3或者从maven3降级到maven2,M2_HOME环境变量改变后,在终端执行mvn -v,出现如下错误: Exception in thread "main ...
- noi.ac上的一套(假)NOI题
noi.ac上的一套(假)NOI题 本来想着可以刷点通过量的,结果发现好像并不是这样的. 整数 description 给你\(n,p\),要你求\(\sum_{k=1}^n\sum_{i=1}^k\ ...
- 0302 IT行业就业与软件工程
阅读以下文章 http://www.thea.cn/news/terminal/9/9389.html http://www.shzhidao.cn/system/2015/09/22/0102610 ...
- POJ3696 The Luckiest number
题意 Language:Default The Luckiest number Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7 ...
- visual studio内置“iis”组件提取及二次开发
简介 visual studio安装后会自带小型的“iis”服务器,本文就简单提取一下这个组件,自己做一个小型“iis”服务器吧.先来说用途吧(废话可绕过),比如在服务器上没有安装iis,或者给客户演 ...