Java垃圾回收機(jī)制

簡介

Java與C++之間有一堵由內(nèi)存動態(tài)分配和垃圾收集技術(shù)所圍成的“高墻”片吊,墻外的人想進(jìn)去礼预,墻里面的人想出來。

Java內(nèi)存運(yùn)行時(shí)區(qū)域中的程序計(jì)數(shù)器疮装、虛擬機(jī)棧、本地方法棧隨線程而生滅粘都;棧中的棧幀隨著方法的進(jìn)入和退出而有條不紊地執(zhí)行著出棧和入棧操作廓推。每一個棧幀中分配多少內(nèi)存基本上是在類結(jié)構(gòu)確定下來時(shí)就已知的(盡管在運(yùn)行期會由JIT編譯器進(jìn)行一些優(yōu)化),因此這幾個區(qū)域的內(nèi)存分配和回收都具備確定性翩隧,不需要過多考慮回收的問題樊展,因?yàn)榉椒ńY(jié)束或者線程結(jié)束時(shí),內(nèi)存自然就跟隨著回收了鸽心。

而Java堆不一樣滚局,一個接口中的多個實(shí)現(xiàn)類需要的內(nèi)存可能不一樣,一個方法中的多個分支需要的內(nèi)存也可能不一樣顽频,我們只有在程序處于運(yùn)行期間時(shí)才能知道會創(chuàng)建哪些對象藤肢,這部分內(nèi)存的分配和回收都是動態(tài)的,垃圾收集器所關(guān)注的是這部分內(nèi)存糯景。

垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供的一種用于在空閑時(shí)間不定時(shí)回收無任何對象引用的對象占據(jù)的內(nèi)存空間的一種機(jī)制嘁圈。垃圾回收回收的是無任何引用的對象占據(jù)的內(nèi)存空間而不是對象本身。換言之蟀淮,垃圾回收只會負(fù)責(zé)釋放那些對象占有的內(nèi)存最住。對象是個抽象的詞,包括引用和其占據(jù)的內(nèi)存空間怠惶。當(dāng)對象沒有任何引用時(shí)其占據(jù)的內(nèi)存空間隨即被收回備用涨缚,此時(shí)對象也就被銷毀。但不能說是回收對象策治,可以理解為一種文字游戲脓魏。

1.判斷對象是否存活

在堆里面存放著Java世界中幾乎所有的對象實(shí)例,垃圾收集器在對堆進(jìn)行回收前,需要確定這些對象之中哪些還“存活”著,哪些已經(jīng)“死去”(即沒有任何途徑使用的對象)筋夏。

1.1 引用計(jì)數(shù)器

給對象添加一引用計(jì)數(shù)器禾进,被引用一次計(jì)數(shù)器值就加 1;當(dāng)引用失效時(shí),計(jì)數(shù)器值就減 1瞳脓;計(jì)數(shù)器為 0 時(shí)缺亮,對象就是不可能再被使用的悔政,簡單高效晚吞,缺點(diǎn)是無法解決對象之間相互循環(huán)引用的問題。

1.2 可達(dá)性分析算法

通過一系列的稱為”GC Roots”的對象作為起始點(diǎn)卓箫,從這些節(jié)點(diǎn)開始向下搜索载矿,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個對象到 GC Roots沒有任何引用鏈相連時(shí)烹卒,則證明此對象是不可用的闷盔。此算法解決了上述循環(huán)引用的問題。

在Java語言中旅急,可作為 GC Roots 的對象包括下面幾種:

虛擬機(jī)棧(棧幀中的本地變量表)中引用的對象逢勾。

方法區(qū)中類靜態(tài)屬性引用的對象。

方法區(qū)中常量引用的對象藐吮。

本地方法棧中 JNI(Native方法)引用的對象

作為GC Roots的節(jié)點(diǎn)主要在全局性的引用與執(zhí)行上下文中溺拱。要明確的是,tracing gc必須以當(dāng)前存活的對象集為Roots谣辞,因此必須選取確定存活的引用類型對象迫摔。GC管理的區(qū)域是Java堆,虛擬機(jī)棧泥从、方法區(qū)和本地方法棧不被GC所管理句占,因此選用這些區(qū)域內(nèi)引用的對象作為GC Roots,是不會被GC所回收的躯嫉。

其中虛擬機(jī)棧和本地方法棧都是線程私有的內(nèi)存區(qū)域纱烘,只要線程沒有終止,就能確保它們中引用的對象的存活祈餐。而方法區(qū)中類靜態(tài)屬性引用的對象是顯然存活的擂啥。常量引用的對象在當(dāng)前可能存活,因此帆阳,也可能是GC roots的一部分哺壶。

1.3 引用類型

在JDK 1.2以前,Java中的引用的定義很傳統(tǒng):如果reference類型的數(shù)據(jù)中存儲的數(shù)值代表的是另一塊內(nèi)存的起始地址蜒谤,就稱這塊內(nèi)存代表著一個引用山宾。而JDK 1.2之后,Java對引用的概念進(jìn)行了擴(kuò)充芭逝,將引用分為強(qiáng)引用(Strong Reference)塌碌、軟引用(Soft Reference)渊胸、弱引用(Weak Reference)旬盯、虛引用(Phantom Reference)4 種,這 4 種引用強(qiáng)度依次逐漸減弱。

強(qiáng)引用就是指在程序代碼之中普遍存在的胖翰,類似”O(jiān)bject obj=new Object()”這類的引用接剩,垃圾收集器永遠(yuǎn)不會回收存活的強(qiáng)引用對象。

軟引用就是指還有用但并非必需的對象萨咳。在系統(tǒng) 將要發(fā)生內(nèi)存溢出異常之前懊缺,將會把這些對象列進(jìn)回收范圍之中進(jìn)行第二次回收。

弱引用也是用來描述非必需對象的培他,被弱引用關(guān)聯(lián)的對象只能生存到下一次垃圾收集發(fā)生之前鹃两。當(dāng)垃圾收集器工作時(shí),無論內(nèi)存是否足夠舀凛,都會回收掉只被弱引用關(guān)聯(lián)的對象俊扳。

虛引用是最弱的一種引用關(guān)系。無法通過虛引用來取得一個對象實(shí)例猛遍。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個對象被收集器回收時(shí)收到一個系統(tǒng)通知馋记。

1.4 可達(dá)性分析過程

不可達(dá)的對象將暫時(shí)處于“緩刑”階段,要真正宣告一個對象死亡懊烤,至少要經(jīng)歷兩次標(biāo)記過程:

如果對象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒有與GC Roots相連接的引用鏈梯醒,那它將會被第一次標(biāo)記并且進(jìn)行一次篩選,篩選的條件是此對象是否有必要執(zhí)行finalize()方法腌紧。

當(dāng)對象沒有覆蓋finalize()方法茸习,或者finalize()方法已經(jīng)被虛擬機(jī)調(diào)用過,虛擬機(jī)將這兩種情況都視為“沒有必要執(zhí)行”寄啼,直接進(jìn)行第二次標(biāo)記逮光。

如果這個對象被判定為有必要執(zhí)行finalize()方法,那么這個對象將會放置在一個叫做F-Queue的隊(duì)列之中墩划,并在稍后由一個由虛擬機(jī)自動建立的涕刚、低優(yōu)先級的Finalizer線程去執(zhí)行它。

這里所謂的“執(zhí)行”是指虛擬機(jī)會觸發(fā)這個方法乙帮,但并不承諾會等待它運(yùn)行結(jié)束杜漠,因?yàn)槿绻粋€對象在finalize()方法中執(zhí)行緩慢,將很可能會一直阻塞F-Queue隊(duì)列察净,甚至導(dǎo)致整個內(nèi)存回收系統(tǒng)崩潰驾茴。

使用finalize()方法來“拯救”對象的方法是不值得提倡的,它的運(yùn)行代價(jià)高昂氢卡,不確定性大锈至,無法保證各個對象的調(diào)用順序。finalize()能做的工作译秦,使用try-finally或者其它方法都更適合峡捡、及時(shí)击碗,所以可以盡量忘記這個方法的存在。

1.5 回收方法區(qū)

永久代的垃圾收集主要回收兩部分內(nèi)容:廢棄常量和無用的類们拙。

回收廢棄常量與回收J(rèn)ava堆中的對象非常類似稍途,假如一個字符串”abc”已經(jīng)進(jìn)入了常量池中,但是當(dāng)前系統(tǒng)沒有任何一個String對象是叫做”abc”的砚婆,也沒有其他地方引用了這個字面量械拍,如果這時(shí)發(fā)生內(nèi)存回收,而且必要的話装盯,這個”abc”常量就會被系統(tǒng)清理出常量池坷虑。常量池中的其他類(接口)、方法埂奈、字段的符號引用也與此類似猖吴。

要判斷一個類是否是“無用的類”的條件則相對苛刻許多,類需要滿足以下3個條件才能算“無用的類”:

該類所有的實(shí)例都已經(jīng)被回收挥转,也就是Java堆中不存在該類的任何實(shí)例海蔽。

加載該類的ClassLoader已經(jīng)被回收。

該類對應(yīng)的java.lang.Class對象沒有在任何地方被引用绑谣,無法在任何地方通過反射訪問該類的方法党窜。

虛擬機(jī)可以對滿足上述3個條件的無用類進(jìn)行回收,這里說的僅僅是“可以”借宵,而并不是和對象一樣幌衣,不使用了就必然會回收。

在大量使用反射壤玫、動態(tài)代理豁护、CGLib等ByteCode框架、動態(tài)生成JSP以及OSGi這類頻繁自定義ClassLoader的場景都需要虛擬機(jī)具備類卸載的功能欲间,以保證永久代不會溢出楚里。

2.垃圾回收算法

垃圾回收算法是垃圾回收的理論基礎(chǔ),這里介紹四種垃圾回收算法:標(biāo)記-清除算法猎贴、復(fù)制算法班缎、標(biāo)記-整理算法及分代收集算法。

2.1 標(biāo)記-清除算法

最基礎(chǔ)的收集算法是“標(biāo)記-清除”(Mark-Sweep)算法她渴,分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記出所有需要回收的對象达址,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對象。

它的主要不足有兩個:

效率問題趁耗,標(biāo)記和清除兩個過程的效率都不高沉唠;

空間問題,標(biāo)記清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片苛败,空間碎片太多可能會導(dǎo)致以后在程序運(yùn)行過程中需要分配較大對象時(shí)满葛,無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動作装蓬。

標(biāo)記—清除算法的執(zhí)行過程如下圖:

2.2 復(fù)制算法

為了解決效率問題,一種稱為“復(fù)制”(Copying)的收集算法出現(xiàn)了纱扭,它將可用內(nèi)存按容量劃分為大小相等的兩塊,每次只使用其中的一塊儡遮。當(dāng)這一塊的內(nèi)存用完了乳蛾,就將還存活著的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉鄙币。

這樣使得每次都是對整個半?yún)^(qū)進(jìn)行內(nèi)存回收肃叶,內(nèi)存分配時(shí)也就不用考慮內(nèi)存碎片等復(fù)雜情況,只要移動堆頂指針十嘿,按順序分配內(nèi)存即可因惭,實(shí)現(xiàn)簡單,運(yùn)行高效绩衷。只是這種算法的代價(jià)是將內(nèi)存縮小為了原來的一半蹦魔。復(fù)制算法的執(zhí)行過程如下圖:

現(xiàn)在的商業(yè)虛擬機(jī)都采用這種算法來回收新生代,IBM研究指出新生代中的對象98%是“朝生夕死”的咳燕,所以并不需要按照1:1的比例來劃分內(nèi)存空間勿决,而是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor招盲。當(dāng)回收時(shí)低缩,將Eden和Survivor中還存活著的對象一次性地復(fù)制到另外一塊Survivor空間上,最后清理掉Eden和剛才用過的Survivor空間曹货。HotSpot虛擬機(jī)默認(rèn)Eden:Survivor = 8:1咆繁,也就是每次新生代中可用內(nèi)存空間為整個新生代容量的90%(其中一塊Survivor不可用),只有10%的內(nèi)存會被“浪費(fèi)”顶籽。當(dāng)然玩般,98%的對象可回收只是一般場景下的數(shù)據(jù),我們沒有辦法保證每次回收都只有不多于10%的對象存活礼饱,當(dāng)Survivor空間不夠用時(shí)壤短,需要依賴其他內(nèi)存(這里指老年代)進(jìn)行分配擔(dān)保(Handle Promotion)。

內(nèi)存的分配擔(dān)保就好比我們?nèi)ャy行借款慨仿,如果我們信譽(yù)很好久脯,在98%的情況下都能按時(shí)償還,于是銀行可能會默認(rèn)我們下一次也能按時(shí)按量地償還貸款镰吆,只需要有一個擔(dān)保人能保證如果我不能還款時(shí)帘撰,可以從他的賬戶扣錢,那銀行就認(rèn)為沒有風(fēng)險(xiǎn)了万皿。內(nèi)存的分配擔(dān)保也一樣摧找,如果另外一塊 Survivor空間沒有足夠空間存放上一次新生代收集下來的存活對象時(shí)核行,這些對象將直接通過分配擔(dān)保機(jī)制進(jìn)入老年代。

2.3 標(biāo)記整理算法

復(fù)制算法在對象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作蹬耘,效率將會變低芝雪。更關(guān)鍵的是,如果不想浪費(fèi)50%的空間综苔,就需要有額外的空間進(jìn)行分配擔(dān)保惩系,以應(yīng)對被使用的內(nèi)存中所有對象都100%存活的極端情況,所以在老年代一般不能直接選用這種算法如筛。

根據(jù)老年代的特點(diǎn)堡牡,有人提出了另外一種“標(biāo)記-整理”(Mark-Compact)算法,標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣杨刨,但后續(xù)步驟不是直接對可回收對象進(jìn)行清理晤柄,而是讓所有存活的對象都向一端移動,然后直接清理掉端邊界以外的內(nèi)存妖胀,“標(biāo)記-整理”算法的示意圖如下:

2.4 分代收集算法

當(dāng)前商業(yè)虛擬機(jī)的垃圾收集都采用“分代收集”(Generational Collection)算法芥颈,根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊并采用不用的垃圾收集算法。

一般是把Java堆分為新生代和老年代赚抡,這樣就可以根據(jù)各個年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ń浇琛T谛律校看卫占瘯r(shí)都發(fā)現(xiàn)有大批對象死去怕品,只有少量存活妇垢,那就選用復(fù)制算法,只需要付出少量存活對象的復(fù)制成本就可以完成收集肉康。而老年代中因?yàn)閷ο蟠婊盥矢叽彻馈]有額外空間對它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記—清理”或者“標(biāo)記—整理”算法來進(jìn)行回收吼和。

3.HotSpot的算法實(shí)現(xiàn)

3.1 枚舉根節(jié)點(diǎn)

以可達(dá)性分析中從GC Roots節(jié)點(diǎn)找引用鏈這個操作為例涨薪,可作為GC Roots的節(jié)點(diǎn)主要在全局性的引用(例如常量或類靜態(tài)屬性)與執(zhí)行上下文(例如棧幀中的本地變量表)中,現(xiàn)在很多應(yīng)用僅僅方法區(qū)就有數(shù)百兆炫乓,如果要逐個檢查這里面的引用刚夺,那么必然會消耗很多時(shí)間。

另外末捣,可達(dá)性分析對執(zhí)行時(shí)間的敏感還體現(xiàn)在GC停頓上侠姑,因?yàn)檫@項(xiàng)分析工作必須不可以出現(xiàn)分析過程中對象引用關(guān)系還在不斷變化的情況,否則分析結(jié)果準(zhǔn)確性就無法得到保證箩做。這點(diǎn)是導(dǎo)致GC進(jìn)行時(shí)必須停頓所有Java執(zhí)行線程(Sun將這件事情稱為”Stop The World”)的其中一個重要原因莽红,即使是在號稱(幾乎)不會發(fā)生停頓的CMS收集器中,枚舉根節(jié)點(diǎn)時(shí)也是必須要停頓的。

因此安吁,目前的主流Java虛擬機(jī)使用的都是準(zhǔn)確式GC(即虛擬機(jī)可以知道內(nèi)存中某個位置的數(shù)據(jù)具體是什么類型醉蚁。),所以當(dāng)執(zhí)行系統(tǒng)停頓下來后鬼店,并不需要一個不漏地檢查完所有執(zhí)行上下文和全局的引用位置网棍,虛擬機(jī)應(yīng)當(dāng)是有辦法直接得知哪些地方存放著對象引用。

在HotSpot的實(shí)現(xiàn)中妇智,是使用一組稱為OopMap的數(shù)據(jù)結(jié)構(gòu)來達(dá)到這個目的的滥玷,在類加載完成的時(shí)候,HotSpot就把對象內(nèi)什么偏移量上是什么類型的數(shù)據(jù)計(jì)算出來俘陷,在JIT編譯過程中,也會在特定的位置記錄棧和寄存器中哪些位置是引用观谦。這樣拉盾,GC在掃描時(shí)就可以直接得知這些信息了。

3.2 安全點(diǎn)(Safepoint)

在OopMap的協(xié)助下豁状,HotSpot可以快速且準(zhǔn)確地完成GC Roots枚舉捉偏,但一個很現(xiàn)實(shí)的問題隨之而來:可能導(dǎo)致引用關(guān)系變化,或者說OopMap內(nèi)容變化的指令非常多泻红,如果為每一條指令都生成對應(yīng)的OopMap夭禽,那將會需要大量的額外空間,這樣GC的空間成本將會變得很高谊路。

實(shí)際上讹躯,HotSpot也的確沒有為每條指令都生成OopMap,前面已經(jīng)提到缠劝,只是在“特定的位置”記錄了這些信息潮梯,這些位置稱為安全點(diǎn),即程序執(zhí)行時(shí)并非在所有地方都能停頓下來開始GC 惨恭,只有在到達(dá)安全點(diǎn)時(shí)才能暫停秉馏。

Safepoint的選定既不能太少以致于GC過少,也不能過于頻繁以致于過分增大運(yùn)行時(shí)的負(fù)荷脱羡。對于Safepoint萝究,另一個需要考慮的問題是如何在GC 發(fā)生時(shí)讓所有線程都“跑”到最近的安全點(diǎn)上再停頓下來。這里有兩種方案可供選擇:搶先式中斷(Preemptive Suspension)和主動式中斷(Voluntary Suspension)锉罐。

其中搶先式中斷不需要線程的執(zhí)行代碼主動去配合帆竹,在GC發(fā)生時(shí),首先把所有線程全部中斷脓规,如果發(fā)現(xiàn)有線程中斷的地方不在安全點(diǎn)上馆揉,就恢復(fù)線程,讓它“跑”到安全點(diǎn)上《独梗現(xiàn)在幾乎沒有虛擬機(jī)實(shí)現(xiàn)采用搶先式中斷來暫停線程從而響應(yīng)GC事件升酣。

而主動式中斷的思想是當(dāng)GC需要中斷線程的時(shí)候舷暮,不直接對線程操作,僅僅簡單地設(shè)置一個標(biāo)志噩茄,各個線程執(zhí)行時(shí)主動去輪詢這個標(biāo)志下面,發(fā)現(xiàn)中斷標(biāo)志為真時(shí)就自己中斷掛起。輪詢標(biāo)志的地方和安全點(diǎn)是重合的绩聘,另外再加上創(chuàng)建對象需要分配內(nèi)存的地方沥割。

3.3 安全區(qū)域(Safe Region)

使用Safepoint似乎已經(jīng)完美地解決了如何進(jìn)入GC的問題,但實(shí)際情況卻并不一定凿菩。Safepoint機(jī)制保證了程序執(zhí)行時(shí)机杜,在不太長的時(shí)間內(nèi)就會遇到可進(jìn)入GC的Safepoint。但是衅谷,程序“不執(zhí)行”的時(shí)候呢椒拗?所謂的程序不執(zhí)行就是沒有分配CPU時(shí)間,典型的例子就是線程處于Sleep狀態(tài)或者Blocked狀態(tài)获黔,這時(shí)候線程無法響應(yīng)JVM的中斷請求蚀苛,“走”到安全的地方去中斷掛起,JVM也顯然不太可能等待線程重新被分配CPU時(shí)間玷氏。對于這種情況堵未,就需要安全區(qū)域(Safe Region)來解決。

安全區(qū)域是指在一段代碼片段之中盏触,引用關(guān)系不會發(fā)生變化渗蟹。在這個區(qū)域中的任意地方開始GC都是安全的。我們也可以把Safe Region看做是被擴(kuò)展了的Safepoint赞辩。在線程執(zhí)行到Safe Region中的代碼時(shí)拙徽,首先標(biāo)識自己已經(jīng)進(jìn)入了Safe Region,那樣诗宣,當(dāng)在這段時(shí)間里JVM要發(fā)起GC時(shí)膘怕,就不用管標(biāo)識自己為Safe Region狀態(tài)的線程了。在線程要離開Safe Region時(shí)召庞,它要檢查系統(tǒng)是否已經(jīng)完成了根節(jié)點(diǎn)枚舉(或者是整個 GC 過程)岛心,如果完成了,那線程就繼續(xù)執(zhí)行篮灼,否則它就必須等待直到收到可以安全離開Safe Region的信號為止忘古。

本文摘自《深入理解Java虛擬機(jī)》

微信號 : silentao_com,歡迎搜索關(guān)注個人同名微信公眾號米蘭半島鐵盒诅诱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末髓堪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌干旁,老刑警劉巖驶沼,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異争群,居然都是意外死亡回怜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門换薄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玉雾,“玉大人,你說我怎么就攤上這事轻要「囱” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵冲泥,是天一觀的道長驹碍。 經(jīng)常有香客問我,道長柏蘑,這世上最難降的妖魔是什么幸冻? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任粹庞,我火速辦了婚禮咳焚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庞溜。我一直安慰自己革半,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布流码。 她就那樣靜靜地躺著又官,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漫试。 梳的紋絲不亂的頭發(fā)上六敬,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音驾荣,去河邊找鬼外构。 笑死,一個胖子當(dāng)著我的面吹牛播掷,可吹牛的內(nèi)容都是我干的审编。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼歧匈,長吁一口氣:“原來是場噩夢啊……” “哼垒酬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤勘究,失蹤者是張志新(化名)和其女友劉穎矮湘,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乱顾,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡板祝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了走净。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片券时。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖伏伯,靈堂內(nèi)的尸體忽然破棺而出橘洞,到底是詐尸還是另有隱情,我是刑警寧澤说搅,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布炸枣,位于F島的核電站,受9級特大地震影響弄唧,放射性物質(zhì)發(fā)生泄漏适肠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一候引、第九天 我趴在偏房一處隱蔽的房頂上張望侯养。 院中可真熱鬧,春花似錦澄干、人聲如沸逛揩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辩稽。三九已至,卻和暖如春从媚,著一層夾襖步出監(jiān)牢的瞬間逞泄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工拜效, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喷众,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓拂檩,卻偏偏與公主長得像侮腹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稻励,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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

  • 來自: Android夢想特工隊(duì)作者: Aaron主頁: http://www.wxtlife.com/原...
    技術(shù)特工隊(duì)閱讀 4,361評論 0 28
  • 1. 概述 在編寫Java程序時(shí)父阻,一般不用內(nèi)存管理愈涩,不用像C++一樣需要在程序中手動釋放內(nèi)存。JVM的垃圾收集器會...
    Coding小聰閱讀 425評論 0 0
  • 無論你是跟同事加矛、同學(xué)履婉、上下級、同行斟览、或者面試官討論技術(shù)問題的時(shí)候毁腿,很容易卷入JVM大型撕逼現(xiàn)場。為了能夠讓大家從大...
    Arthinking閱讀 502評論 0 0
  • Java語言是一門自動內(nèi)存管理的語言苛茂,不再需要的對象可以通過垃圾回收自動進(jìn)行內(nèi)存釋放已烤。 Java運(yùn)行時(shí)內(nèi)存區(qū)域劃分...
    zhong0316閱讀 742評論 0 3
  • 一、常用垃圾回收機(jī)制 1. 標(biāo)記-清除算法(mark-sweep) 顧名思義妓羊,標(biāo)記-清除算法分為兩個階段胯究,標(biāo)記(m...
    molscar閱讀 303評論 0 0