国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JAVA 垃圾收集器與內(nèi)存分配策略

AlanKeene / 530人閱讀

摘要:引言垃圾收集技術(shù)并不是語(yǔ)言首創(chuàng)的,年誕生于的是第一門真正使用內(nèi)存動(dòng)態(tài)分配和垃圾收集技術(shù)的語(yǔ)言。垃圾收集器所關(guān)注的就是這部分內(nèi)存。收集器是收集器的多線程版,它是第一款并發(fā)收集器。經(jīng)常出現(xiàn)大對(duì)象會(huì)導(dǎo)致多次出發(fā)垃圾收集。

引言

垃圾收集技術(shù)并不是Java語(yǔ)言首創(chuàng)的,1960年誕生于MIT的Lisp是第一門真正使用內(nèi)存動(dòng)態(tài)分配和垃圾收集技術(shù)的語(yǔ)言。垃圾收集技術(shù)需要考慮的三個(gè)問(wèn)題是:

哪些內(nèi)存需要回收?
什么時(shí)候回收?
如何回收?

http://segmentfault.com/a/119... 中講到j(luò)ava內(nèi)存運(yùn)行時(shí)區(qū)域的分布,其中程序計(jì)數(shù)器,虛擬機(jī)棧,本地方法區(qū)都是隨著線程而生,隨線程而滅,所以這幾個(gè)區(qū)域就不需要過(guò)多考慮回收問(wèn)題。但是堆和方法區(qū)就不一樣了,只有在程序運(yùn)行期間我們才知道會(huì)創(chuàng)建哪些對(duì)象,這部分內(nèi)存的分配和回收都是動(dòng)態(tài)的。垃圾收集器所關(guān)注的就是這部分內(nèi)存。

一 對(duì)象死亡判據(jù)

垃圾收集器在對(duì)一個(gè)對(duì)象回收之前,首先要判斷對(duì)象在程序中是否還有使用的可能性,充要條件就是沒(méi)有被程序可訪問(wèn)的引用再指向這個(gè)對(duì)象實(shí)例。最簡(jiǎn)單的辦法就是給對(duì)象實(shí)例添加中添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)引用指向它時(shí),計(jì)數(shù)器就加一,當(dāng)引用失效時(shí),計(jì)數(shù)器就減一,如果計(jì)數(shù)器值為0則說(shuō)明沒(méi)有引用指向它,可以進(jìn)行回收。但是這個(gè)方法中計(jì)數(shù)器為0并不是一個(gè)必要條件,例如,生成兩個(gè)對(duì)象實(shí)例,每個(gè)對(duì)象實(shí)例的屬性都指向?qū)Ψ剑敲催@個(gè)兩個(gè)對(duì)象實(shí)例分別最少有一個(gè)引用。

java采用的是可達(dá)性分析算法,即找一部分對(duì)象作為"GC Roots"節(jié)點(diǎn),從這些節(jié)點(diǎn)開(kāi)始向下搜索,當(dāng)某個(gè)對(duì)象到"GC Roots"節(jié)點(diǎn)沒(méi)有可達(dá)路徑時(shí),說(shuō)明此對(duì)象是不可用的。在java中作為"GC Roots"的節(jié)點(diǎn)包括:

虛擬機(jī)棧中引用的對(duì)象,

方法區(qū)靜態(tài)屬性引用的對(duì)象,

方法區(qū)常量引用的對(duì)象,

本地方法區(qū)中本地調(diào)用所引用的對(duì)象。

引用擴(kuò)充

如果reference類型的數(shù)據(jù)中存儲(chǔ)的數(shù)值是另一塊內(nèi)存的起始地址,那么這塊內(nèi)存就代表著一個(gè)引用。一個(gè)對(duì)象在這種狀態(tài)下,只能有被引用和沒(méi)有被引用兩種狀態(tài)。java對(duì)引用概念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用(new),軟引用(softReference),弱引用(WeakReference),虛引用(PhantomReference)。如果強(qiáng)引用存在,則垃圾收集器不會(huì)回收該對(duì)象。如果系統(tǒng)即將發(fā)生內(nèi)存溢出異常,那么垃圾回收集器則會(huì)回收軟引用對(duì)象。弱引用對(duì)象只能存活到下一次垃圾收集之前。虛引用對(duì)象不會(huì)對(duì)其生存時(shí)間構(gòu)成任何影響。

對(duì)象的自我救贖

在垃圾收集器發(fā)現(xiàn)某一個(gè)對(duì)象到"GC Roots"路徑不可達(dá)時(shí),先會(huì)判斷該對(duì)象是否覆蓋finalize()方法,或是否執(zhí)行過(guò)finalize()方法。如果覆蓋了且沒(méi)有執(zhí)行過(guò)該方法,則會(huì)將該對(duì)象放到低優(yōu)先級(jí)的Finalizer線程隊(duì)列中去執(zhí)行finalize()方法,如果在finalize()方法中該對(duì)象又被引用,則會(huì)有一次逃脫被回收的命運(yùn)。

方法區(qū)的回收

方法區(qū)中主要回收廢棄的常量和無(wú)用的類。對(duì)于常量,如果沒(méi)有引用指向常量,則該常量會(huì)被回收。對(duì)于類的回收則麻煩許多,首先要判斷該類是無(wú)用的類無(wú)用的類要滿足三個(gè)條件:

所有類的實(shí)例被回收。

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

Class沒(méi)有被引用,不會(huì)通過(guò)反射訪問(wèn)該類的方法。

二 垃圾回收算法 標(biāo)記-清除算法(Mark-Sweep)

該算法分為兩個(gè)階段:首先標(biāo)記處要回收的對(duì)象,標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。
存在的問(wèn)題:

標(biāo)記和清除效率都不高

標(biāo)記清除后會(huì)產(chǎn)生大量?jī)?nèi)存碎片,分配大對(duì)象時(shí)可能觸發(fā)另一次垃圾收集。

復(fù)制算法(Copying)

該算法將內(nèi)存分為兩個(gè)等大小的區(qū)域,每次只使用一個(gè)區(qū)域。當(dāng)一個(gè)區(qū)域快用完了,就將這個(gè)區(qū)域中存活的對(duì)象復(fù)制到另一個(gè)區(qū)域。

優(yōu)點(diǎn)是避免了內(nèi)存碎片的產(chǎn)生,缺點(diǎn)是浪費(fèi)內(nèi)存空間。

有公司研究表明,新生代的對(duì)象98%都是朝生暮死,所以虛擬機(jī)把新生代內(nèi)存劃分為一個(gè)較大的Eden空間和兩個(gè)較小的Survivor空間。每次只是用Eden空間和一個(gè)Survior空間,當(dāng)進(jìn)行復(fù)制清理時(shí),將Survivor空間和Eden空間中存活的對(duì)象復(fù)制到另一塊Survivor空間。當(dāng)Survivor空間不夠用時(shí),就會(huì)依賴?yán)夏甏M(jìn)行分配擔(dān)保。

標(biāo)記-整理算法(Mark-Compact)

針對(duì)老年代對(duì)象存活率高的情況,復(fù)制算法明顯不合適,于是采用標(biāo)記整理算法,標(biāo)記和標(biāo)記清除算法相同,二后邊的整理則是讓所有存活的對(duì)象都向一端移動(dòng),然后清理掉邊界外的內(nèi)存。

分代收集

當(dāng)前虛擬機(jī)都采用分代收集,分代的依據(jù)是對(duì)象的存活周期。一般新生代存活率低,采用復(fù)制算法。老年代存活率高采用標(biāo)記整理標(biāo)記清除

一般來(lái)講,新生代空間會(huì)小很多,具體比例一般要看應(yīng)用場(chǎng)景。而默認(rèn)的大小一般是老年代的1/4到1/3。

三 垃圾收集器


由于虛擬機(jī)采用了分代收集,所以針對(duì)不同代收集器也不同。上圖是HotSpot虛擬機(jī)的垃圾收集器,連線表示可以協(xié)同工作。

Serial收集器,復(fù)制算法,它是一個(gè)單線程的收集器,并且在進(jìn)行收集時(shí)會(huì)暫停其他線程,它默認(rèn)是client模式下的新生代收集器。

ParNew收集器是Serial收集器的多線程版,它是第一款并發(fā)收集器。

Parallel Scavenge收集器可以精確控制吞吐量(用戶代碼運(yùn)行時(shí)間/(用戶代碼時(shí)間+垃圾收集時(shí)間))

SerialOld收集器是serial收集器的老年版,采用標(biāo)記整理算法,同樣是單線程收集器。

ParallelOld是ParallelScavenge收集器的老年版,使用多線程和標(biāo)記整理算法。

CMS收集器是以最短回收停頓時(shí)間為目標(biāo)的收集器,采用標(biāo)記清除算法,在重視響應(yīng)速度的系統(tǒng)中得以應(yīng)用。但是缺點(diǎn)是對(duì)CPU資源敏感,無(wú)法處理浮動(dòng)垃圾,易產(chǎn)生內(nèi)存碎片。

G1收集器是最新推出的收集器,可應(yīng)用在JDK1.7u4及以上版本。它將內(nèi)存分為多個(gè)Region,新生代和老年代分別包含多個(gè)Region。G1跟蹤各個(gè)Region,判斷垃圾價(jià)值大小,優(yōu)先回收價(jià)值最大的Region。

安全點(diǎn)

安全點(diǎn)的概念是指當(dāng)進(jìn)行GC時(shí),應(yīng)當(dāng)讓工作線程停止,這時(shí)會(huì)更容易對(duì)對(duì)象是否存活進(jìn)行判斷。而停止線程應(yīng)當(dāng)在安全的時(shí)刻,所以會(huì)有安全點(diǎn)的概念。

暫停線程有兩種方式,第一種是強(qiáng)制暫停,如果某些線程沒(méi)有到達(dá)安全點(diǎn)則再讓他運(yùn)行到安全點(diǎn),這叫做搶先式中斷。第二種是在編譯過(guò)程中在安全點(diǎn)加入一個(gè)條件判斷判斷0x160100內(nèi)存頁(yè)是否可讀,如果不可讀則會(huì)暫停,這叫做主動(dòng)式中斷

四 內(nèi)存分配與回收策略


對(duì)象的分配,就是在堆上分配,對(duì)象主要分配在新生代的Eden區(qū)域中,如果啟動(dòng)了本地線程分配緩沖,則按線程優(yōu)先在TLAB中分配。少數(shù)情況也有可能直接分配到老年代。

對(duì)象在Eden區(qū)域分配時(shí),當(dāng)Eden區(qū)域沒(méi)有足夠空間,虛擬機(jī)會(huì)發(fā)起一次新生代垃圾收集。

如果對(duì)象需要大量連續(xù)內(nèi)存空間,例如String類型和數(shù)組。大對(duì)象對(duì)于虛擬機(jī)內(nèi)存分配來(lái)說(shuō)是一個(gè)壞消息,朝生暮死的大對(duì)象是要命的壞消息。經(jīng)常出現(xiàn)大對(duì)象會(huì)導(dǎo)致多次出發(fā)垃圾收集。對(duì)于這類對(duì)象,可以設(shè)置參數(shù)將大對(duì)象直接存入老年代。

每一個(gè)對(duì)象都有一個(gè)年齡計(jì)數(shù)器,當(dāng)對(duì)象在Eden區(qū)域出生,每經(jīng)過(guò)一次GC,并且存入Survivor,計(jì)數(shù)器加一。當(dāng)年齡增加到一定程度(默認(rèn)15),則會(huì)被存入老年代。同時(shí),如果Survivor空間中相同年齡對(duì)象占空間超過(guò)50%,則也會(huì)直接進(jìn)入老年代。

總結(jié)

垃圾收集算法:復(fù)制算法標(biāo)記-清除算法標(biāo)記-清理算法

垃圾收集器特點(diǎn):新生代用復(fù)制,老年代用標(biāo)記清理,CMS用標(biāo)記清除。

Eden空間大小和Survivor空間大小默認(rèn)比率為8:1,即新生代10%的空間用來(lái)存放復(fù)制后的對(duì)象。

更多文章:http://blog.gavinzh.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/64403.html

相關(guān)文章

  • 《深入理解Java虛擬機(jī)第3版》垃圾集器內(nèi)存分配策略、虛擬機(jī)性能監(jiān)控故障處理工具

    摘要:目錄往期博客課堂篇初識(shí)常量池簡(jiǎn)單理解字符串常量池靜態(tài)常量池大整型常量池為什么要了解垃圾收集和內(nèi)存分配如何判斷對(duì)象已死引用計(jì)數(shù)算法可達(dá)性分析算法之后引用的擴(kuò)充回收方法區(qū)垃圾收集算法分代收集理論標(biāo)記清除標(biāo)記復(fù)制標(biāo)記整理對(duì)象分 ...

    Kerr1Gan 評(píng)論0 收藏0
  • 《深入理解java虛擬機(jī)》學(xué)習(xí)筆記系列——垃圾集器&內(nèi)存分配策略

    摘要:虛擬機(jī)所處的區(qū)域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機(jī)總共運(yùn)行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數(shù)量為。 本文主要從GC(垃圾回收)的角度試著對(duì)jvm中的內(nèi)存分配策略與相應(yīng)的垃圾收集器做一個(gè)介紹。 注:還是老規(guī)矩,本著能畫(huà)圖就不BB原則,盡量將各知識(shí)點(diǎn)通過(guò)思維導(dǎo)圖或者其他模型圖的方式進(jìn)行說(shuō)明。文字僅記錄額外的思考與心得,以及其他特殊情況 內(nèi)存...

    calx 評(píng)論0 收藏0
  • 《深入理解Java虛擬機(jī)》(三)垃圾集器內(nèi)存分配策略

    摘要:當(dāng)兩個(gè)對(duì)象相互引用時(shí),這兩個(gè)對(duì)象就不會(huì)被回收引用計(jì)數(shù)算法不被主流虛擬機(jī)采用,主要原因是它很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題。 垃圾收集器與內(nèi)存分配策略 詳解 3.1 概述 本文參考的是周志明的 《深入理解Java虛擬機(jī)》第三章 ,為了整理思路,簡(jiǎn)單記錄一下,方便后期查閱。 3.2 對(duì)象已死嗎 在垃圾收集器進(jìn)行回收前,第一件事就是確定這些對(duì)象哪些還存活,哪些已經(jīng)死去。 3.2.1 引用...

    Edison 評(píng)論0 收藏0
  • 【讀書(shū)筆記】JVM垃圾收集內(nèi)存分配策略

    摘要:堆和方法區(qū)只有在程序運(yùn)行時(shí)才能確定內(nèi)存的使用情況,垃圾回收器所關(guān)注的主要就是這部分內(nèi)存。虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整比率參數(shù)以提供最合適的停頓時(shí)間或最大的吞吐量。 Tip:內(nèi)容為對(duì)《深入理解Java虛擬機(jī)》(周志明 著)第三章內(nèi)容的總結(jié)和筆記。這是第一次拜讀時(shí)讀到的一些重點(diǎn),做個(gè)分享,也為后面再次閱讀和實(shí)踐做保障。 3.1 概述 程序計(jì)數(shù)器、虛擬機(jī)棧、本地...

    mcterry 評(píng)論0 收藏0
  • 摘記《深入理解Java虛擬機(jī):JVM高級(jí)特性最佳實(shí)踐(第2版)》

    摘要:第章內(nèi)存區(qū)域與內(nèi)存溢出異常運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。即對(duì)象指向它的類元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定這個(gè)對(duì)象是哪個(gè)類的實(shí)例。 第2章 Java內(nèi)存區(qū)域與內(nèi)存溢出異常 2.2 運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。根據(jù)《Java虛擬機(jī)規(guī)范(Java SE 7版)...

    zoomdong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<