Java引用詳解

1 Java中的四種引用

在Java中提供了四個(gè)級(jí)別的引用:強(qiáng)引用返十,軟引用,弱引用和虛引用吸奴。在這四個(gè)引用類型中,只有強(qiáng)引用FinalReference類是包內(nèi)可見(jiàn),其他三種引用類型均為public则奥,可以在應(yīng)用程序中直接使用考润。引用類型的類結(jié)構(gòu)如圖所示。

1.1 強(qiáng)引用

Java中的強(qiáng)引用指的是逞度,程序中有直接可達(dá)的引用额划。如

    Object obj = new Object();

強(qiáng)引用的特點(diǎn):

  1. 強(qiáng)引用可以直接訪問(wèn)目標(biāo)對(duì)象妙啃。
  2. 強(qiáng)引用所指向的對(duì)象在任何時(shí)候都不會(huì)被系統(tǒng)回收档泽。JVM寧愿拋出OOM異常,也不會(huì)回收強(qiáng)引用所指向的對(duì)象揖赴。
  3. 強(qiáng)引用可能導(dǎo)致內(nèi)存泄漏馆匿。

1.2 軟引用

軟引用是除了強(qiáng)引用外,最強(qiáng)的引用類型燥滑〗ケ保可以通過(guò)java.lang.ref.SoftReference使用軟引用。

SoftReference<Object> softRef = new SoftReference<Object>(new Object());

軟引用的特點(diǎn):

1.軟引用的對(duì)象铭拧,只有在內(nèi)存不足的時(shí)候(拋出OOM異常前)赃蛛,垃圾收集器會(huì)決定回收該軟引用所指向的對(duì)象。軟引用通常用于實(shí)現(xiàn)內(nèi)存敏感的緩存搀菩。

2.在垃圾線程對(duì) 這個(gè)Java對(duì)象回收前呕臂,SoftReference類所提供的get()方法返回Java對(duì)象的強(qiáng)引用。一旦垃圾線程回收該Java對(duì)象之后肪跋,get()方法將返回null歧蒋。

1.3 弱引用

弱引用是一種比軟引用較弱的引用類型≈菁龋可以用java.lang.ref.WeakReference實(shí)例來(lái)保存對(duì)一個(gè)Java對(duì)象的弱引用谜洽。

WeakReference<Object> weakRef = new WeakReference<Object>(new Object());

軟引用的特點(diǎn):

1.不管內(nèi)存是否足夠,只要被垃圾收集器發(fā)現(xiàn)吴叶,該引用的對(duì)象就會(huì)被回收

1.4 虛引用

虛引用是所有類型中最弱的一個(gè)阐虚。一個(gè)持有虛引用的對(duì)象,和沒(méi)有引用幾乎是一樣的蚌卤,可以用java.lang.ref.WeakReference實(shí)例來(lái)保存對(duì)一個(gè)Java對(duì)象的弱引用实束。

Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
PhantomReference<Object> phantom = new PhantomReference<Object>(obj, refQueue);

虛引用的特點(diǎn):

1.隨時(shí)可能被垃圾回收器回收。

2.當(dāng)試圖通過(guò)虛引用的get()方法取得強(qiáng)引用時(shí)造寝,總是返回null磕洪。

3.虛引用必須和引用隊(duì)列一起使用。

當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)诫龙,如果發(fā)現(xiàn)它還有虛引用析显,就會(huì)在垃圾回收后,銷毀這個(gè)對(duì)象签赃,將這個(gè)虛引用加入引用隊(duì)列谷异。程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用分尸,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列歹嘹,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)箩绍。

2 ReferenceQueue

引用隊(duì)列,當(dāng)檢測(cè)到對(duì)象的可到達(dá)性更改時(shí)尺上,垃圾回收器將已注冊(cè)的引用對(duì)象添加到隊(duì)列中材蛛,ReferenceQueue實(shí)現(xiàn)了入隊(duì)(enqueue)和出隊(duì)(poll),還有remove操作怎抛,內(nèi)部元素head就是泛型的Reference卑吭。

//創(chuàng)建一個(gè)引用隊(duì)列  
ReferenceQueue queue = new ReferenceQueue();  

// 創(chuàng)建弱引用,此時(shí)狀態(tài)為Active马绝,并且Reference.pending為空豆赏,當(dāng)前Reference.queue = 上面創(chuàng)建的queue,并且next=null  
WeakReference reference = new WeakReference(new Object(), queue);  
System.out.println(reference);  
// 當(dāng)GC執(zhí)行后富稻,由于是弱引用掷邦,所以回收該object對(duì)象,并且置于pending上椭赋,此時(shí)reference的狀態(tài)為PENDING  
System.gc();  

/* ReferenceHandler從pending中取下該元素抚岗,并且將該元素放入到queue中,此時(shí)Reference狀態(tài)為ENQUEUED纹份,Reference.queue = ReferenceENQUEUED */  

/* 當(dāng)從queue里面取出該元素苟跪,則變?yōu)镮NACTIVE,Reference.queue = Reference.NULL */  
Reference reference1 = queue.remove();  
System.out.println(reference1);

3 源碼分析

3.1Reference定義的4種狀態(tài)

Reference類首先把內(nèi)存分為4種狀態(tài)Active蔓涧,Pending件已,Enqueued,Inactive元暴。

  • Active庞萍,一般來(lái)說(shuō)內(nèi)存一開(kāi)始被分配的狀態(tài)都是 Active燎悍,
  • Pending 大概是指快要被放進(jìn)隊(duì)列的對(duì)象,也就是馬上要回收的對(duì)象,
  • Enqueued 就是對(duì)象的內(nèi)存已經(jīng)被回收了裙盾,我們已經(jīng)把這個(gè)對(duì)象放入到一個(gè)隊(duì)列中伙窃,方便以后我們查詢某個(gè)對(duì)象是否被回收择膝,
  • Inactive就是最終的狀態(tài)奢米,不能再變?yōu)槠渌鼱顟B(tài)。

3.2 Reference成員變量

// 用于保存對(duì)象的引用讶迁,GC會(huì)根據(jù)不同Reference來(lái)特別對(duì)待
private T referent;
// 如果需要通知機(jī)制连茧,則保存的對(duì)對(duì)應(yīng)的隊(duì)列
ReferenceQueue<? super T> queue;
/* 這個(gè)用于實(shí)現(xiàn)一個(gè)單向循環(huán)鏈表,用以將保存需要由ReferenceHandler處理的引用 */
Reference next;

static private class Lock { };
// 鎖,用于同步pending隊(duì)列的進(jìn)隊(duì)和出隊(duì)
private static Lock lock = new Lock();

transient private Reference<T> discovered;  /* used by VM */  

// 此屬性保存一個(gè)PENDING的隊(duì)列啸驯,配合上述next一起使用
private static Reference pending = null;
  • referent表示其引用的對(duì)象客扎,即在構(gòu)造的時(shí)候需要被包裝在其中的對(duì)象。
  • queue 是對(duì)象即將被回收時(shí)所要通知的隊(duì)列罚斗。當(dāng)對(duì)象即將被回收時(shí)徙鱼,整個(gè)reference對(duì)象,而不僅僅是被回收的對(duì)象针姿,會(huì)被放到queue 里面袱吆,然后外部程序即可通過(guò)監(jiān)控這個(gè) queue 即可拿到相應(yīng)的數(shù)據(jù)了。
  • next 即當(dāng)前引用節(jié)點(diǎn)所存儲(chǔ)的下一個(gè)即將被處理的節(jié)點(diǎn)搓幌。但 next 僅在放到queue中才會(huì)有意義杆故,因?yàn)橹挥性趀nqueue的時(shí)候,會(huì)將next設(shè)置為下一個(gè)要處理的Reference對(duì)象溉愁。為了描述相應(yīng)的狀態(tài)值,在放到隊(duì)列當(dāng)中后饲趋,其queue就不會(huì)再引用這個(gè)隊(duì)列了拐揭。而是引用一個(gè)特殊的 ENQUEUED(內(nèi)部定義的一個(gè)空隊(duì)列)。因?yàn)橐呀?jīng)放到隊(duì)列當(dāng)中奕塑,并且不會(huì)再次放到隊(duì)列當(dāng)中堂污。
  • discovered 表示要處理的對(duì)象的下一個(gè)對(duì)象。即可以理解要處理的對(duì)象也是一個(gè)鏈表龄砰,通過(guò)discovered進(jìn)行排隊(duì)盟猖,這邊只需要不停地拿到pending,然后再通過(guò)discovered 不斷地拿到下一個(gè)對(duì)象賦值給pending即可换棚,直到取到了最有一個(gè)式镐。它是被JVM 使用的。
  • pending 是等待被入隊(duì)的引用列表固蚤。JVM 收集器會(huì)添加引用到這個(gè)列表娘汞,直到Reference-handler線程移除了它們。這個(gè)列表使用 discovered 字段來(lái)連接它下一個(gè)元素(即 pending 的下一個(gè)元素就是discovered對(duì)象夕玩。r = pending; pending = r.discovered)你弦。

3.3 ReferenceQueue成員變量

// 用于標(biāo)識(shí)沒(méi)有注冊(cè)Queue
static ReferenceQueue NULL = new Null();
// 用于標(biāo)識(shí)已經(jīng)處于對(duì)應(yīng)的Queue中
static ReferenceQueue ENQUEUED = new Null();

static private class Lock { };
/* 互斥鎖,用于同步ReferenceHandler的enqueue和用戶線程操作的remove和poll出隊(duì)操作 */
private Lock lock = new Lock();
// 隊(duì)列
private volatile Reference<? extends T> head = null;
// 隊(duì)列中的元素個(gè)數(shù)
private long queueLength = 0;

3.4 對(duì)象的入隊(duì)過(guò)程

當(dāng) Reference 類被加載的時(shí)候燎孟,會(huì)執(zhí)行靜態(tài)代碼塊禽作。在靜態(tài)代碼塊里面,會(huì)啟動(dòng) ReferenceHandler 線程,并設(shè)置線程的級(jí)別為最大級(jí)別揩页, Thread.MAX_PRIORITY旷偿。

檢查 pending 是否為 null,如果pending不為 null,則將 pending 進(jìn)行 enqueue狸捅,否則線程進(jìn)入 wait 狀態(tài)衷蜓。

private static class ReferenceHandler extends Thread {
   ----- // 核心代碼如下
    public void run() {
        while (true) {
            tryHandlePending(true);
        }
    }
static boolean tryHandlePending(boolean waitForNotify) {
    Reference<Object> r;
    Cleaner c;
    try {
        synchronized (lock) {
            // 檢查 pending 是否為 null,不為 null尘喝,制定 pending enqueue
            if (pending != null) {
                r = pending;
                // 'instanceof' might throw OutOfMemoryError sometimes
                // so do this before un-linking 'r' from the 'pending' chain...
                c = r instanceof Cleaner ? (Cleaner) r : null;
                // unlink 'r' from 'pending' chain
                pending = r.discovered;
                r.discovered = null;
            } else { // 為 null磁浇。等待
                // The waiting on the lock may cause an OutOfMemoryError
                // because it may try to allocate exception objects.
                if (waitForNotify) {
                    lock.wait();
                }
                // retry if waited
                return waitForNotify;
            }
        }
    } catch (OutOfMemoryError x) {
        // Give other threads CPU time so they hopefully drop some live references
        // and GC reclaims some space.
        // Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
        // persistently throws OOME for some time...
        Thread.yield();
        // retry
        return true;
    } catch (InterruptedException x) {
        // retry
        return true;
    }

    // Fast path for cleaners
    if (c != null) {
        c.clean();
        return true;
    }
    ReferenceQueue<? super Object> q = r.queue;
    if (q != ReferenceQueue.NULL) q.enqueue(r);
    return true;
  }
}

/******************************ReferenceQueue*************************/

boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
    synchronized (lock) {
        // Check that since getting the lock this reference hasn't already been
        // enqueued (and even then removed)
        ReferenceQueue<?> queue = r.queue;
        // queue 為 null 或者 queue 已經(jīng)被回收了,直接返回
        if ((queue == NULL) || (queue == ENQUEUED)) {
            return false;
        }
        assert queue == this;
        // 將 Reference 的狀態(tài)置為 Enqueued朽褪,表示已經(jīng)被回收
        r.queue = ENQUEUED;
        // 接著置吓,將 Reference 插入到鏈表
        // 判斷當(dāng)前鏈表是否為 null,不為 null缔赠,將 r.next 指向 head衍锚,為 null,head 直接指向 r
        r.next = (head == null) ? r : head;
        // head 指針指向 r
        head = r;
        queueLength++;
        if (r instanceof FinalReference) {
            sun.misc.VM.addFinalRefCount(1);
        }
        lock.notifyAll();
        return true;
    }
}

注意:

  1. JVM在GC時(shí)會(huì)把回收了內(nèi)存的對(duì)象的'Reference'通過(guò)'discovered'連接成鏈表嗤堰。

  2. ‘pending’屬性相對(duì)于'discovered'鏈表上面的指針戴质,每次把當(dāng)前的元素放入引用隊(duì)列,然后指向鏈表的下一個(gè)元素踢匣。

  3. 'Reference'的'next'屬于用于指向一個(gè)已經(jīng)在隊(duì)列中被回收的對(duì)象告匠。

4 Object的finalize()方法原理

4.1 finalize()方法簡(jiǎn)介

  • 如果一個(gè)類實(shí)現(xiàn)了finalize方法,那么GC在回收這個(gè)對(duì)象之前离唬,會(huì)將finalize方法進(jìn)行調(diào)用后专。finalize的一般約定是,jvm虛擬機(jī)已經(jīng)確定沒(méi)有任何引用或者線程訪問(wèn)此對(duì)象输莺,就會(huì)調(diào)用這個(gè)finalize方法戚哎。在finalize方法中可以進(jìn)行任何操作,包括該對(duì)象再次對(duì)其他線程進(jìn)行調(diào)用嫂用。這個(gè)方法的目的是在gc回收對(duì)象之前型凳,再次對(duì)之前未關(guān)閉的資源進(jìn)行回收。如IO操作中的連接等尸折。
  • java虛擬機(jī)并不保證哪個(gè)線程會(huì)具體調(diào)用finalize方法啰脚,但是可以保證調(diào)用finalize方法的時(shí)候不會(huì)有任何用戶可見(jiàn)的同步鎖。如果finalize方法中出現(xiàn)任何異常实夹,則這些異常會(huì)被忽略橄浓,且finalize方法會(huì)終止。
  • 在一個(gè)對(duì)象調(diào)用finalize方法之后亮航,在jvm確認(rèn)這個(gè)對(duì)象沒(méi)有任何其他對(duì)象能訪問(wèn)之前,也就是說(shuō)jvm確認(rèn)這個(gè)對(duì)象不是垃圾之前缴淋。finalize方法不會(huì)執(zhí)行泄朴。
  • finalize 方法只會(huì)被虛擬機(jī)執(zhí)行一次。
  • finalize方法中的異常會(huì)被忽略祖灰,之后finalize方法會(huì)終止。

4.2 FinalReference

FinalReference的實(shí)現(xiàn)非常簡(jiǎn)單局扶,這個(gè)類不是public的,其作用域在protected三妈,也就是說(shuō)除了java.lang.ref包中的類能訪問(wèn)之外,不能在任何自定義的代碼中調(diào)用畴蒲。這也說(shuō)明這是一個(gè)jvm才能訪問(wèn)的類。

class FinalReference<T> extends Reference<T> {

    public FinalReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }
}

4.3 Finalizer

Finalizer是finalReference的子類模燥,對(duì)queue和lock進(jìn)行了重寫(xiě)。Finalizer也是protected作用域软驰,另外通過(guò)final修飾涧窒。不可被繼承。

//final修飾的類不可被繼承
final class Finalizer extends FinalReference<Object> { 

   //重寫(xiě)了queue屬性锭亏,F(xiàn)inalizer必須使用ReferenceQueue,因此一開(kāi)始就對(duì)queue進(jìn)行了實(shí)例化
    private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
    private static Finalizer unfinalized = null;
    //重載了鎖
    private static final Object lock = new Object();

    //鏈表指針,F(xiàn)inalizer是個(gè)雙向鏈表
    private Finalizer
        next = null,
        prev = null;
}

4.4 FinalizerThread

jvm在注冊(cè)的時(shí)候硬鞍,實(shí)際上就是創(chuàng)建了一個(gè)Finalizer的鏈表慧瘤。在GC的時(shí)候,如果發(fā)現(xiàn)對(duì)象只被Finalizer引用固该,則說(shuō)明這個(gè)對(duì)象可以被回收了锅减。那么就將其從引用對(duì)象鏈中取出,放入ReferenceQueue中伐坏。之后通知Finalizer Thread線程去消費(fèi)怔匣。之后去調(diào)用finalize方法。


private static class FinalizerThread extends Thread {
        private volatile boolean running;
        FinalizerThread(ThreadGroup g) {
            super(g, "Finalizer");
        }
        public void run() {
            if (running)
                return;

            // Finalizer thread starts before System.initializeSystemClass
            // is called.  Wait until JavaLangAccess is available
            while (!VM.isBooted()) {
                // delay until VM completes initialization
                try {
                    VM.awaitBooted();
                } catch (InterruptedException x) {
                    // ignore and continue
                }
            }
            final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
            running = true;
            for (;;) {
                try {
                    Finalizer f = (Finalizer)queue.remove();
                    f.runFinalizer(jla);
                } catch (InterruptedException x) {
                    // ignore and continue
                }
            }
        }
    }
/*********************************Finalizer****************************/

private void runFinalizer(JavaLangAccess jla) {
        synchronized (this) {
            if (hasBeenFinalized()) return;
            remove();
        }
        try {
            Object finalizee = this.get();
            if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
                jla.invokeFinalize(finalizee);

                /* Clear stack slot containing this variable, to decrease
                   the chances of false retention with a conservative GC */
                finalizee = null;
            }
        } catch (Throwable x) { }
        super.clear();
    }

流程:

  • 在創(chuàng)建對(duì)象的時(shí)候桦沉,如果重寫(xiě)了finalize方法每瞒,jvm就會(huì)同時(shí)創(chuàng)建一個(gè)Finalizer對(duì)象。
  • 所有的Finalizer對(duì)象構(gòu)成一個(gè)雙向鏈表
  • 所有的Finalizer對(duì)象都有一個(gè)名為queue的ReferenceQueue隊(duì)列
  • GC在執(zhí)行標(biāo)記的最后階段纯露,會(huì)把Finalizer的對(duì)象加入到Reference的pending-list 鏈表中剿骨。
  • ReferenceHandler會(huì)將pending-list中的對(duì)象取出,放置到這個(gè)ReferenceQueue中埠褪。對(duì)于finalReference而言浓利,這個(gè)queue即使初始化的時(shí)候創(chuàng)建的static的queue挤庇。對(duì)于所有的FinalReference全局只有一個(gè)ReferenceQueue。
  • Finalizer中有一個(gè)專門(mén)的守護(hù)線程 Finalizer Thread,這個(gè)線程中有一個(gè)死循環(huán)贷掖,專門(mén)從queue中取出對(duì)象嫡秕,并執(zhí)行Finalizer中引用對(duì)象的finalize方法。之后從隊(duì)列中移除苹威,強(qiáng)引用消除昆咽。
  • 再次GC 這個(gè)Finalizer的對(duì)象沒(méi)有任何引用,因此可能被回收掉屠升。

java虛引用的使用說(shuō)明 - followus - 博客園

Java Reference 源碼分析 - Jabnih - 博客園

java 源碼系列 - 帶你讀懂 Reference 和 ReferenceQueue_gdutxiaoxu的博客(微信公眾號(hào) stormjun94)-CSDN博客

java中的reference(三): FinalReference和Finalizer的源碼分析_dhaibo1986的專欄-CSDN博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末潮改,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腹暖,更是在濱河造成了極大的恐慌汇在,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糕殉,死亡現(xiàn)場(chǎng)離奇詭異殖告,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)羡洁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)筑煮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)真仲,“玉大人初澎,你說(shuō)我怎么就攤上這事碑宴。” “怎么了焰宣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵匕积,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我盅粪,道長(zhǎng)票顾,這世上最難降的妖魔是什么帆调? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任番刊,我火速辦了婚禮芹务,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘熔吗。我一直安慰自己佳晶,他們只是感情好轿秧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布淤刃。 她就那樣靜靜地躺著逸贾,像睡著了一般铝侵。 火紅的嫁衣襯著肌膚如雪触徐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天疟丙,我揣著相機(jī)與錄音享郊,去河邊找鬼。 笑死展蒂,一個(gè)胖子當(dāng)著我的面吹牛苔咪,可吹牛的內(nèi)容都是我干的团赏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼隘世,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丙者!你這毒婦竟也來(lái)了械媒?” 一聲冷哼從身側(cè)響起评汰,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤被去,失蹤者是張志新(化名)和其女友劉穎糜值,沒(méi)想到半個(gè)月后寂汇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡榕栏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年硼被,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嚷硫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仔掸。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡起暮,死狀恐怖会烙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纸厉,我是刑警寧澤颗品,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布躯枢,位于F島的核電站槐臀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏败匹。R本人自食惡果不足惜讥巡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一欢顷、第九天 我趴在偏房一處隱蔽的房頂上張望抬驴。 院中可真熱鬧,春花似錦豌拙、人聲如沸题暖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)况芒。三九已至绝骚,卻和暖如春祠够,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛾魄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工滴须, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叽奥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓魔市,卻偏偏與公主長(zhǎng)得像待德,于是被迫代替她去往敵國(guó)和親枫夺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在堆里存放著幾乎多有的java對(duì)象實(shí)例法竞,垃圾搜集器在對(duì)堆進(jìn)行回收之前,第一件事情就是確定這些對(duì)象之中哪些還“存活”...
    fishlovecat閱讀 97評(píng)論 0 0
  • 在堆里存放著幾乎多有的java對(duì)象實(shí)例侦鹏,垃圾搜集器在對(duì)堆進(jìn)行回收之前,第一件事情就是確定這些對(duì)象之中哪些還“存活”...
    kylinxiang閱讀 27,858評(píng)論 2 15
  • 概述 Java的引用分為StrongReference价卤、SoftReference慎璧、WeakReference跨释、P...
    allanYan閱讀 362評(píng)論 0 0
  • 1鳖谈、引用級(jí)別 在JVM中,垃圾回收器一直在背后默默地承擔(dān)著內(nèi)存回收的工作捷绒,我們不需要像使用C語(yǔ)音開(kāi)發(fā)那樣小心翼翼地...
    冰河winner閱讀 988評(píng)論 0 1
  • 大家都知道java里面引用有SoftReference暖侨、WeakReference崇渗、PhantomReferenc...
    Java天天閱讀 456評(píng)論 0 0