- 浏览: 981054 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Java NIO ByteBuffer详解:http://donald-draper.iteye.com/blog/2357084
MappedByteBuffer定义:http://donald-draper.iteye.com/blog/2371594
整理 Java 引用(Reference)的概念 :https://www.oschina.net/question/12_8662
Java 中的 Reference:http://www.cnblogs.com/newcj/archive/2011/05/15/2046882.html
引言:
这一篇文章,我们没有打算深入研究java的Reference的机制和及各种类型引用与垃圾回收器的关系,我们仅仅看一下Reference的定义,由于本人的能力有限,现在还不能够完全理解Reference,我们仅仅窥探一下内部的结构,在简单看一下PhantomReference,Cleaner。
//Reference
在Reference的pending集合处理线程ReferenceHandler中,入队列后,
如果引用对象为Cleaner,则Clean,下面我们来看clean操作做了什么
//Cleaner
再看Cleaner的clean操作之前,我们先来看一下PhantomReference
//PhantomReference
当GC一但发现了虚引用对象,将会将PhantomReference对象插入ReferenceQueue队列,
而此时PhantomReference所指向的对象并没有被GC回收,而是要等到ReferenceQueue被你真正的处理后才会被回收。
回到Cleaner,我们来看他的clear操作:
总结:
Cleaner关联一个清除线程thunk和cleaner,在手动clean一个引用对象cleaner(PhantomReference)时,首先从引用对应队列ReferenceQueue移除引用对象,再执行清除线程thunk,完成实际的清除工作。了解Cleaner才是我们写这篇文章的目的,这个会在DirectByteBuffer中用到,我们在后面的文章会在讲,以便更深刻的理解Cleaner的作用。
MappedByteBuffer定义:http://donald-draper.iteye.com/blog/2371594
整理 Java 引用(Reference)的概念 :https://www.oschina.net/question/12_8662
Java 中的 Reference:http://www.cnblogs.com/newcj/archive/2011/05/15/2046882.html
引言:
这一篇文章,我们没有打算深入研究java的Reference的机制和及各种类型引用与垃圾回收器的关系,我们仅仅看一下Reference的定义,由于本人的能力有限,现在还不能够完全理解Reference,我们仅仅窥探一下内部的结构,在简单看一下PhantomReference,Cleaner。
//Reference
package java.lang.ref; import sun.misc.Cleaner; /** * Abstract base class for reference objects. This class defines the * operations common to all reference objects. Because reference objects are * implemented in close cooperation with the garbage collector, this class may * not be subclassed directly. *Reference为引用对象的抽象基础类。Reference定义了所有引用对象的一般操作。Reference用于垃圾 回收器先关操作中,Reference不能够直接subclassed。 * @author Mark Reinhold * @since 1.2 */ public abstract class Reference<T> { /* A Reference instance is in one of four possible internal states: *一个引用实例可能有以下四种内部状态 * 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. * Active:被垃圾回收器对待为一个Subject,如果垃圾回收器探测到引用的可达性 达到一个适当状态,将改变实例的状态为Pending or Inactive,这个依赖于,在实例创建时, 实例是否注册到队列。Pending状态,一个实例将会添加到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. * Pending:pending-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. * Enqueued:实例创建时注册到队列。当实例从ReferenceQueue中移除,则为Inactive。 已经反注册的实例不会处于此状态。 * 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: *各状态在队列中的编码和next指针如下: * Active: queue = ReferenceQueue with which instance is registered, or * ReferenceQueue.NULL if it was not registered with a queue; next = * null. * Active:queue为注册实例的ReferenceQueue或者ReferenceQueue.NULL(还没有注册到队列), next指针为null * Pending: queue = ReferenceQueue with which instance is registered; * next = Following instance in queue, or this if at end of list. * Pending:queue为实例注册到的队列ReferenceQueue,next执行队列中的紧跟着的元素, 在队列尾部,next为this。 * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance * in queue, or this if at end of list. * Enqueued:queue 为ReferenceQueue.ENQUEUED;next执行队列中的紧跟着的元素, 在队列尾部,next为this。 * Inactive: queue = ReferenceQueue.NULL; next = this. * 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,就可以确定一个引用的实例对象是否 需要特殊对待:若果next为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引用对象,垃圾回收应该通过discovered连接到需要发现或查找的对象。 */ private T referent; /* Treated specially by GC */ ReferenceQueue<? super T> queue;//对象的引用队列 Reference next;//下一个引用对象 transient private Reference<T> discovered; /* used by VM */ /* 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. lock用于垃圾回收器同步。在每次回收垃圾的开始时,必须获取此锁。因此任何拥有此锁的 代码必须尽可能快的完成, allocate no new objects, and avoid calling user code. */ static private class Lock { }; private static Lock lock = new Lock(); /* List of References waiting to be enqueued. The collector adds * References to this list, while the Reference-handler thread removes * them. This list is protected by the above lock object. 等待入队列的引用集合。当引用被 Reference-handler线程移除时,垃圾回收器将会添加 引用到pending集合。集合使用lock对象保护。 */ private static Reference pending = null; /* High-priority thread to enqueue pending References 高优先级pending References入队列线程 */ private static class ReferenceHandler extends Thread { ReferenceHandler(ThreadGroup g, String name) { super(g, name); } public void run() { for (;;) { Reference r; synchronized (lock) { if (pending != null) { r = pending; Reference rn = r.next; //引用指向自己则为null,否则为pending的next pending = (rn == r) ? null : rn; r.next = r; } else { try { //否则等待 lock.wait(); } catch (InterruptedException x) { } continue; } } // Fast path for cleaners if (r instanceof Cleaner) { //如果pending为Cleaner,则clean,这个我们在后面在讲 ((Cleaner)r).clean(); continue; } ReferenceQueue q = r.queue; //如果引用队列不为空,则入队列 if (q != ReferenceQueue.NULL) q.enqueue(r); } } } static { ThreadGroup tg = Thread.currentThread().getThreadGroup(); //获取当前现成的顶级父线程组 for (ThreadGroup tgn = tg; tgn != null; tg = tgn, tgn = tg.getParent()); Thread handler = new ReferenceHandler(tg, "Reference Handler"); /* If there were a special system-only priority greater than * MAX_PRIORITY, it would be used here */ handler.setPriority(Thread.MAX_PRIORITY); handler.setDaemon(true); //启动pending集合处理线程 handler.start(); } /* -- Referent accessor and setters -- */ /** * Returns this reference object's referent. If this reference object has * been cleared, either by the program or by the garbage collector, then * this method returns <code>null</code>. *返回对象的引用者。如果这个引用对象被应用或者来及回收器清除,将会返回null。 * @return The object to which this reference refers, or * <code>null</code> if this reference object has been cleared */ public T get() { return this.referent; } /** * Clears this reference object. Invoking this method will not cause this * object to be enqueued. *清除引用对象,调用此方不会引起对象入队列。 * <p> This method is invoked only by Java code; when the garbage collector * clears references it does so directly, without invoking this method. 此方法通过Java代码调用,垃圾回收器直接清除引用,不会调用此方法 */ public void clear() { this.referent = null; } /* -- Queue operations -- */ /** * Tells whether or not this reference object has been enqueued, either by * the program or by the garbage collector. If this reference object was * not registered with a queue when it was created, then this method will * always return <code>false</code>. *判断一个引用对象是否通过程序或垃圾回收器入队列,如果引用对象在创建时没有注册 到队列,则此方返回fasle。 * @return <code>true</code> if and only if this reference object has * been enqueued */ public boolean isEnqueued() { /* In terms of the internal states, this predicate actually tests whether the instance is either Pending or Enqueued */ //如果引用队列不为空,则next不为null synchronized (this) { return (this.queue != ReferenceQueue.NULL) && (this.next != null); } } /** * Adds this reference object to the queue with which it is registered, * if any. *引用对象注册时添加到队列 * <p> This method is invoked only by Java code; when the garbage collector * enqueues references it does so directly, without invoking this method. *此方通过java代码调用,垃圾回收器直接入队列引用,不会调用此方法 * @return <code>true</code> if this reference object was successfully * enqueued; <code>false</code> if it was already enqueued or if * it was not registered with a queue when it was created */ public boolean enqueue() { return this.queue.enqueue(this); } /* -- Constructors -- */ Reference(T referent) { this(referent, null); } Reference(T referent, ReferenceQueue<? super T> queue) { this.referent = referent; this.queue = (queue == null) ? ReferenceQueue.NULL : queue; } } 再来看ReferenceQueue package java.lang.ref; /** * Reference queues, to which registered reference objects are appended by the * garbage collector after the appropriate reachability changes are detected. *在引用对象路径可达状态改变被垃圾回收器探测到时,垃圾回收器注册引用对象到引用队列。 * @author Mark Reinhold * @since 1.2 */ public class ReferenceQueue<T> { /** * Constructs a new reference-object queue. */ public ReferenceQueue() { } private static class Null extends ReferenceQueue { boolean enqueue(Reference r) { return false; } } //NULL引用队列 static ReferenceQueue NULL = new Null(); //已经入队列的引用 static ReferenceQueue ENQUEUED = new Null(); static private class Lock { }; private Lock lock = new Lock();//同步锁 private volatile Reference<? extends T> head = null;//队列头部 private long queueLength = 0;//队列长度 //将引用添加到引用队列头部 boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */ synchronized (r) { //如果已经入队列则返回false if (r.queue == ENQUEUED) return false; synchronized (lock) { r.queue = ENQUEUED; //获取队列头部 r.next = (head == null) ? r : head; head = r; queueLength++;//队列长度自增 if (r instanceof FinalReference) { //如果引用为FinalReference,则虚拟机不可变引用计数器+1 sun.misc.VM.addFinalRefCount(1); } //唤醒所有等待lock的操作 lock.notifyAll(); return true; } } } //从引用队列取出一个引用对象 private Reference<? extends T> reallyPoll() { /* Must hold lock */ if (head != null) { Reference<? extends T> r = head; head = (r.next == r) ? null : r.next; //重置引用对象的引用队列为NUll r.queue = NULL; r.next = r; queueLength--; if (r instanceof FinalReference) { //如果引用为FinalReference,则虚拟机不可变引用计数器-1 sun.misc.VM.addFinalRefCount(-1); } return r; } return null; } /** * Polls this queue to see if a reference object is available. If one is * available without further delay then it is removed from the queue and * returned. Otherwise this method immediately returns <tt>null</tt>. *从引用队列取一个引用对象,查看引用对象是否可用。如果可用,则从引用队列移除, 否则返回null * @return A reference object, if one was immediately available, * otherwise <code>null</code> */ public Reference<? extends T> poll() { if (head == null) return null; synchronized (lock) { return reallyPoll(); } } /** * Removes the next reference object in this queue, blocking until either * one becomes available or the given timeout period expires. *移除队列的下一个引用对象,阻塞到对象可用,或者超时 * <p> This method does not offer real-time guarantees: It schedules the * timeout as if by invoking the {@link Object#wait(long)} method. *此方法不能保证超时时间的准确性。通过Object#wait(long)方法调度时间。 * @param timeout If positive, block for up to <code>timeout</code> * milliseconds while waiting for a reference to be * added to this queue. If zero, block indefinitely. * * @return A reference object, if one was available within the specified * timeout period, otherwise <code>null</code> * * @throws IllegalArgumentException * If the value of the timeout argument is negative * * @throws InterruptedException * If the timeout wait is interrupted */ public Reference<? extends T> remove(long timeout) throws IllegalArgumentException, InterruptedException { if (timeout < 0) { throw new IllegalArgumentException("Negative timeout value"); } synchronized (lock) { Reference<? extends T> r = reallyPoll(); //如果对象可用,理解返回 if (r != null) return r; for (;;) { //否则自旋超时等地下一个引用对象可用。 lock.wait(timeout); r = reallyPoll(); if (r != null) return r; if (timeout != 0) return null; } } } /** * Removes the next reference object in this queue, blocking until one * becomes available. *移除队列的下一个引用对象,阻塞到引用对象可用 * @return A reference object, blocking until one becomes available * @throws InterruptedException If the wait is interrupted */ public Reference<? extends T> remove() throws InterruptedException { return remove(0); } }
在Reference的pending集合处理线程ReferenceHandler中,入队列后,
如果引用对象为Cleaner,则Clean,下面我们来看clean操作做了什么
// Fast path for cleaners if (r instanceof Cleaner) { //如果pending为Cleaner,则clean,这个我们在后面在讲 ((Cleaner)r).clean(); continue; } //Reference-ReferenceHandler private static class ReferenceHandler extends Thread { ReferenceHandler(ThreadGroup g, String name) { super(g, name); } public void run() { for (;;) { Reference r; synchronized (lock) { if (pending != null) { r = pending; Reference rn = r.next; //引用指向自己则为null,否则为pending的next pending = (rn == r) ? null : rn; r.next = r; } else { try { //否则等待 lock.wait(); } catch (InterruptedException x) { } continue; } } // Fast path for cleaners if (r instanceof Cleaner) { //如果pending为Cleaner,则clean,这个我们在后面在讲 ((Cleaner)r).clean(); continue; } ReferenceQueue q = r.queue; //如果引用队列不为空,则入队列 if (q != ReferenceQueue.NULL) q.enqueue(r); } }
//Cleaner
package sun.misc; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; public class Cleaner extends PhantomReference {
再看Cleaner的clean操作之前,我们先来看一下PhantomReference
//PhantomReference
package java.lang.ref; /** * Phantom reference objects, which are enqueued after the collector * determines that their referents may otherwise be reclaimed. Phantom * references are most often used for scheduling pre-mortem cleanup actions in * a more flexible way than is possible with the Java finalization mechanism. * * <p> If the garbage collector determines at a certain point in time that the * referent of a phantom reference is <a * href="package-summary.html#reachability">phantom reachable</a>, then at that * time or at some later time it will enqueue the reference. * * <p> In order to ensure that a reclaimable object remains so, the referent of * a phantom reference may not be retrieved: The <code>get</code> method of a * phantom reference always returns <code>null</code>. * * <p> Unlike soft and weak references, phantom references are not * automatically cleared by the garbage collector as they are enqueued. An * object that is reachable via phantom references will remain so until all * such references are cleared or themselves become unreachable. * * @author Mark Reinhold * @since 1.2 */ public class PhantomReference<T> extends Reference<T> { /** * Returns this reference object's referent. Because the referent of a * phantom reference is always inaccessible, this method always returns * <code>null</code>. *返回引用对象的引用者。由于PhantomReference总是不可访问的,所以总是返回null。 * @return <code>null</code> */ public T get() { return null; } /** * Creates a new phantom reference that refers to the given object and * is registered with the given queue. *创建一个PhantomReference引用注册到指定队列的指定对象。 * <p> It is possible to create a phantom reference with a <tt>null</tt> * queue, but such a reference is completely useless: Its <tt>get</tt> * method will always return null and, since it does not have a queue, it * will never be enqueued. *有可能创建一个PhantomReference,它的引用队列为null,此引用完全无用, 由于没有入引用队列,所以get方法总是返回null * @param referent the object the new phantom reference will refer to * @param q the queue with which the reference is to be registered, * or <tt>null</tt> if registration is not required */ public PhantomReference(T referent, ReferenceQueue<? super T> q) { super(referent, q); } }
当GC一但发现了虚引用对象,将会将PhantomReference对象插入ReferenceQueue队列,
而此时PhantomReference所指向的对象并没有被GC回收,而是要等到ReferenceQueue被你真正的处理后才会被回收。
回到Cleaner,我们来看他的clear操作:
package sun.misc; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; public class Cleaner extends PhantomReference { private static final ReferenceQueue dummyQueue = new ReferenceQueue();//引用队列 private static Cleaner first = null;//头部 private Cleaner next;//后继 private Cleaner prev;//先驱 private final Runnable thunk; //构造Cleaner private Cleaner(Object obj, Runnable runnable) { super(obj, dummyQueue); next = null; prev = null; thunk = runnable; } //根据给定的obj和线程创建Cleaner,并添加到Cleaner链表中 public static Cleaner create(Object obj, Runnable runnable) { if(runnable == null) return null; else return add(new Cleaner(obj, runnable)); } //添加Cleaner到Cleaner链表中 private static synchronized Cleaner add(Cleaner cleaner) { if(first != null) { cleaner.next = first; first.prev = cleaner; } first = cleaner; return cleaner; } 从Cleaner的链表中移除cleaner private static synchronized boolean remove(Cleaner cleaner) { if(cleaner.next == cleaner) return false; if(first == cleaner) if(cleaner.next != null) first = cleaner.next; else first = cleaner.prev; if(cleaner.next != null) cleaner.next.prev = cleaner.prev; if(cleaner.prev != null) cleaner.prev.next = cleaner.next; cleaner.next = cleaner; cleaner.prev = cleaner; return true; } //清除操作 public void clean() { //如果移除clear失败,则直接返回 if(!remove(this)) return; try { //运行清除线程 thunk.run(); } catch(final Throwable x) { AccessController.doPrivileged(new PrivilegedAction() { public Void run() { //如果清除异常,则抛出错误 if(System.err != null) (new Error("Cleaner terminated abnormally", x)).printStackTrace(); System.exit(1); return null; } public volatile Object run() { return run(); } final Throwable val$x; final Cleaner this$0; { this$0 = Cleaner.this; x = throwable; super(); } }); } } }
总结:
Cleaner关联一个清除线程thunk和cleaner,在手动clean一个引用对象cleaner(PhantomReference)时,首先从引用对应队列ReferenceQueue移除引用对象,再执行清除线程thunk,完成实际的清除工作。了解Cleaner才是我们写这篇文章的目的,这个会在DirectByteBuffer中用到,我们在后面的文章会在讲,以便更深刻的理解Cleaner的作用。
发表评论
-
ThreadLocal解析
2017-04-08 15:36 1332Spring+Mybatis多数据源的实现:http://do ... -
VIsualVM与MemoryAnalyzer分析堆内存过程
2017-02-25 14:06 6070背景:有个一数据库记录增量更新线程,运行过程中,吃内存较大,打 ... -
java虚拟机内存查看相关命令
2017-02-23 20:03 4185关于cmd命令的重定向输出 :http://blog.csdn ... -
Java动态代理
2016-12-01 10:49 555深入浅析Spring 的aop实现原理:http://www. ... -
Java Stack用法
2016-10-13 09:58 1599java.util.Stack类简介 :http://blog ... -
JVM,ConcurrentMarkSweep垃圾回收器实战分析
2016-10-11 18:37 1664堆内存设置:http://blog.csdn.net/sivy ... -
深入理解Collections的unmodifiableMap(Map map)方法
2016-09-23 08:40 5076深刻理解IdentityHashMap:http://dona ... -
深刻理解IdentityHashMap
2016-09-22 16:34 2365新建POJO package test; public ...
相关推荐
1. 创建引用子类的实例,如`SoftReference`, `WeakReference`, 或 `PhantomReference`。 2. 将引用实例与目标对象关联。 3. 使用`get()`方法检查引用是否仍然有效。对于软引用和弱引用,如果对象被回收,`get()`将...
4. 虚引用(PhantomReference):虚引用,该引用必须和引用队列(ReferenceQueue)一起使用,一般用于实现追踪垃圾收集器的回收动作,比如在对象被回收的时候,会调用该对象的finalize方法,在使用虚引用可以实现该...
在Java中,`Reference`类是一个特殊的抽象类,用于表示对象之间的弱引用、软引用和 phantom 引用。这些引用类型允许程序员创建对对象的引用,这些引用在垃圾收集器决定何时回收对象方面具有不同程度的影响。`...
PhantomReference<Object> phanRef = new PhantomReference(obj, refQueue); 在上面的代码中,phanRef 是一个虚引用,它会在垃圾回收器发现虚引用对象时将其插入 ReferenceQueue 队列中。 引用类型的使用场景 ...
这些引用类型主要包括`StrongReference`、`WeakReference`、`SoftReference`和`PhantomReference`,每种都有其特定的用途和行为。 1. **StrongReference**: 强引用是Java中最常见的引用类型,由默认的赋值操作...
Java从1.2版本开始引入了四种引用,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。这四种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用...
- **例子**:` PhantomReference<Object> phantomRef = new PhantomReference(new Object(), new ReferenceQueue());` - **特点**:虚引用主要用来跟踪对象被垃圾收集的状态,通常不用于内存管理。 了解和正确...
总结,java.lang.ref 包中的四种引用类型——StrongReference、SoftReference、WeakReference 和 PhantomReference,提供了不同的内存管理策略,适应不同的场景需求。强引用是最常用的引用类型,但在处理大对象或...
虚引用使用PhantomReference帮助我们定义虚引用。虚引用的特点是不会影响对象的垃圾回收,但可以跟踪对象的垃圾回收过程。 Threadlocal: Threadlocal是一个线程局部变量,可以记录线程的状态。Threadlocal的key...
- 幻象引用,也称为虚引用,是最弱的引用类型,通过`java.lang.ref.PhantomReference`实现。它不直接指向对象,甚至无法通过幻象引用访问对象。幻象引用的主要用途是在对象被finalize之后,但还没有被垃圾收集之前...
- 示例:`PhantomReference<String> phantomRef = new PhantomReference(new String("PhantomReference Test"), new ReferenceQueue());` 理解这四种引用类型有助于开发者在设计和实现复杂系统时,更好地控制对象...
PhantomReference<Object> phantomRef = new PhantomReference(new Object(), queue); ``` 虚引用主要用于实现对象的“finalize”机制,即在对象被垃圾回收前执行一些清理工作,如关闭文件等。当垃圾回收器准备回收...
在JAVA中,虚引用的使用可以通过PhantomReference类来实现,PhantomReference类继承自java.lang.ref.Reference类,它提供了get()和enqueue()两个方法,get()方法用于获取虚引用的对象实例,enqueue()方法用于将虚...
2. `sun.misc.Cleaner`: 这个类是Java的资源清理机制的一部分,通常与`PhantomReference`一起使用,实现类似C++的析构函数功能。`Cleaner`允许程序员注册清理动作,当对象被垃圾收集器回收时,这些清理动作会被执行...
本文将深入探讨Java中三种特殊的引用类型——软引用(Soft Reference)、弱引用(Weak Reference)以及虚引用(Phantom Reference),并分析它们如何帮助我们更好地管理内存资源。 #### 二、基础知识回顾 在深入了解这三...
- 使用** Cleaner / PhantomReference**:对于更复杂的情况,可以使用Cleaner或者PhantomReference来实现更精细的资源清理,但这种方式比直接使用try-finally更复杂,一般只在必要时使用。 5. Java 9及以后版本的...
- 示例:`PhantomReference pr = new PhantomReference(new String("hello"), queue);` - 通常用于管理堆外内存,如 DirectByteBuffer,当对象将被回收时,可以做一些额外的清理工作。 ThreadLocal 工作原理: - ...
Java中的资源回收补救主要涉及两个关键机制:`finalize`方法和`Cleaner`(也称为`PhantomReference`)。这两个机制都是为了确保程序在执行过程中有效地管理并释放非内存资源,如文件句柄、数据库连接或网络套接字等...
- 示例:`PhantomReference<String> phantomRef = new PhantomReference(new String("Hello"), new ReferenceQueue());` 这些引用类型的使用需要根据具体需求来选择。例如,软引用常用于缓存策略,以保持一定数量...
在OpenJDK 11中,`java.lang.ref.Cleaner`作为`PhantomReference`的替代品出现,提供了一种更简单的资源清理机制。开发者可以通过`Cleaner`创建自定义的清理任务,当对象不再被强引用时,可以自动执行清理操作,避免...