sun.misc.Cleaner原始碼解析
前請先看《一提到Reference 99.99%的java程式設計師都懵逼了》,否則裡面的講解會看不懂!弄懂了Reference看下我寫的註釋就輕鬆明白Cleaner原理
Cleaner原始碼解析
/*
* Copyright (c) 2003, 2013, Oracle and/or itsaffiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES ORTHIS FILE HEADER.
*
* This code is free software; you canredistribute it and/or modify it
* under the terms of the GNU General PublicLicense version 2 only, as
* published by the Free SoftwareFoundation. Oracle designates this
* particular file as subject to the "Classpath"exception as provided
* by Oracle in the LICENSE file thataccompanied this code.
*
* This code is distributed in the hope that itwill be useful, but WITHOUT
* ANY WARRANTY; without even the impliedwarranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy isincluded in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNUGeneral Public License version
* 2 along with this work; if not, write to theFree Software Foundation,
* Inc., 51 Franklin St, FifthFloor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway,Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you needadditional information or have any
* questions.
*/
packagesun.misc;
import java.lang.ref.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* General-purpose phantom-reference-based cleaners.
*
* <p> Cleaners are a lightweight and more robust alternativeto finalization.
* They are lightweight because they are notcreated by the VM and thus do not
* require a JNI upcall to be created,and because their cleanup code is
* invoked directly by the reference-handler thread ratherthan by the
* finalizer thread. They are more robust because they use phantomreferences,
* the weakest type of reference object,thereby avoiding the nasty ordering
* problems inherent to finalization.
*
* <p> A cleaner tracks a referent object and encapsulates athunkof arbitrary
* cleanup code. Some time after the GC detects that acleaner's referent has
* become phantom-reachable, the reference-handler thread willrun the cleaner.
* Cleaners may also be invoked directly; theyare thread safe and ensure that
* they run their thunks at most once.
*
* <p> Cleaners are not a replacement for finalization. They should be used
* only when the cleanup code is extremelysimple and straightforward.
* Nontrivial cleaners are inadvisable sincethey risk blocking the
* reference-handler thread and delaying further cleanupand finalization.
*
*
* @author MarkReinhold
*/
//繼承自PhantomReference
publicclassCleaner
extendsPhantomReference<Object>
{
// Dummy reference queue, needed becausethe PhantomReference constructor
// insists that we pass a queue. Nothing will ever be placed on this queue
// since the reference handler invokescleaners explicitly.
//Cleaner引用的ReferenceQueue佇列,靜態全域性變數,如果你看過ReferenceHander執行緒的處理過程,就會知道,Cleaner物件經過ReferenceHander執行緒處理後是不會進入這個佇列的,設定它是為了讓Cleaner物件進入到pending佇列,能夠被ReferenceHander執行緒處理到,沒有設定佇列的Reference物件gc時會直接變為nactive狀態,不會進入pending佇列,詳情看我的另外一篇文章《一提到Reference 99.99%的java程式設計師都懵逼了》中關於Reference物件的狀態轉換
privatestaticfinalReferenceQueue<Object>dummyQueue =newReferenceQueue<>();
// Doubly-linked list of live cleaners,which prevents the cleaners
// themselves from being GC'd before theirreferents
// first變數與next、prev變數一起構建一個雙向連結串列, 我給它起了個名字叫unClean佇列,first是佇列的頭部,靜態變數,所以進入這個佇列的物件都不會被回收,Cleaner物件建立的時候會加入這個連結串列,回收之前會先從這個連結串列中被移除,出隊入隊操作都是在佇列頭部,所以太是一個後進先出佇列,unClean佇列的作用是保持對Cleaner物件的強引用,防止Cleaner物件在它引用的物件之前被垃圾回收器回收掉;
staticprivate Cleanerfirst =null;
privateCleaner
next =null,
prev =null;
//unClean佇列入隊操作 ,加入到佇列頭部
privatestaticsynchronized Cleaneradd(Cleanercl) {
if (first !=null) {
cl.next =first;
first.prev =cl;
}
first =cl;
returncl;
}
//unclean佇列的出隊操作,從頭部出隊
privatestaticsynchronizedboolean remove(Cleaner cl) {
// If already removed, do nothing
if (cl.next==cl)
returnfalse;
// Update list
if (first ==cl) {
if (cl.next!=null)
first =cl.next;
else
first =cl.prev;
}
if (cl.next!=null)
cl.next.prev=cl.prev;
if (cl.prev!=null)
cl.prev.next=cl.next;
// Indicate removal by pointing the cleaner to itself
cl.next =cl;
cl.prev =cl;
returntrue;
}
//實現Runable介面的物件,這個物件會在實現的run方法裡做gc前清理資源的操作,它的run方法最終會由ReferenceHander執行緒來呼叫執行
privatefinal Runnablethunk;
//私有的構造方法,說明Cleaner物件是無法直接被建立的,引數為被引用的物件和ReferenceQueue成員變數
privateCleaner(Objectreferent,Runnablethunk){
super(referent,dummyQueue);
this.thunk =thunk;
}
//這個create靜態方法提供給我們來例項化Cleaner物件,需要兩個引數,被引用的物件與實現了Runnable介面的物件,新建立的Cleaner物件被加入到了unclean佇列裡
/**
* Creates a new cleaner.
*
* @param obthe referent object to be cleaned
* @param thunk
* The cleanup code to be run when the cleaner is invoked. The
* cleanup code is run directly from the reference-handler thread,
* so it should be as simple and straightforward as possible.
*
* @return The new cleaner
*/
publicstatic Cleaner create(Objectob, Runnable thunk) {
if (thunk ==null)
returnnull;
returnadd(new Cleaner(ob,thunk));
}
//clean方法先將物件從unclean佇列移除(這樣Cleaner物件就可以被gc回收掉了),然後呼叫thunk的run方法執行清理操作
/**
* Runs this cleaner, if it has not beenrun before.
*/
publicvoid clean() {
if (!remove(this))
return;
try {
thunk.run();
} catch (final Throwablex) {
AccessController.doPrivileged(newPrivilegedAction<Void>() {
public Void run() {
if (System.err != null)
new Error("Cleaner terminated abnormally",x)
.printStackTrace();
System.exit(1);
returnnull;
}});
}
}
}
相關文章
- 【原始碼解析】- ArrayList原始碼解析,絕對詳細原始碼
- Spark原始碼-SparkContext原始碼解析Spark原始碼Context
- CountDownLatch原始碼解析CountDownLatch原始碼
- LeakCanary原始碼解析原始碼
- vuex原始碼解析Vue原始碼
- ArrayBlockQueue原始碼解析BloC原始碼
- AsyncTask原始碼解析原始碼
- CopyOnWriteArrayList原始碼解析原始碼
- Express原始碼解析Express原始碼
- Observer原始碼解析Server原始碼
- SparseArray 原始碼解析原始碼
- RecyclerView原始碼解析View原始碼
- Promise 原始碼解析Promise原始碼
- Koa原始碼解析原始碼
- RateLimiter原始碼解析MIT原始碼
- redux原始碼解析Redux原始碼
- SDWebImage原始碼解析Web原始碼
- CyclicBarrier原始碼解析原始碼
- Semaphore原始碼解析原始碼
- Exchanger原始碼解析原始碼
- AbstractQueuedSynchronizer原始碼解析原始碼
- OKio原始碼解析原始碼
- Koa 原始碼解析原始碼
- RxPermission原始碼解析原始碼
- MyBatis原始碼解析MyBatis原始碼
- ArrayList原始碼解析原始碼
- Aspects 原始碼解析原始碼
- LeakCanary 原始碼解析原始碼
- Vue原始碼解析Vue原始碼
- React原始碼解析React原始碼
- ButterKnife原始碼解析原始碼
- HashSet原始碼解析原始碼
- Retrofit 原始碼解析原始碼
- Javapoet原始碼解析Java原始碼
- Vuex 原始碼解析Vue原始碼
- OKHttp原始碼解析HTTP原始碼
- Retrofit原始碼解析原始碼
- Handler原始碼解析原始碼