《深入理解java虛擬機(jī)》- 02 GC

1、對(duì)象是否存活

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

可達(dá)性分析

(1) java是通過(guò)可達(dá)性分析來(lái)判定對(duì)象是否存活:通過(guò)GC Roots的對(duì)象作為起始點(diǎn)向下搜索,搜索走過(guò)的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí),證明該對(duì)象不可用届谈。如上圖所示,Object5和Object6到GC Roots沒(méi)有引用鏈弯汰,它們將被判定為可回收對(duì)象

(2) 可作為GC Roots的對(duì)象包括:

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

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

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

本地方法棧中JNI(即一般說(shuō)的Native方法)引用的對(duì)象

1.2 引用概念的擴(kuò)充

(1) 強(qiáng)引用:類似Object obj = new Object()的引用艰山,只要強(qiáng)引用還在,永遠(yuǎn)不會(huì)被GC回收

(2) 軟引用:通過(guò)SoftReference實(shí)現(xiàn)軟引用咏闪,虛擬機(jī)將要拋出OutOfMemoryError異常之前程剥,將會(huì)發(fā)起一次GC動(dòng)作,回收掉所有非強(qiáng)引用的對(duì)象

(3) 弱引用:通過(guò)WeakReference實(shí)現(xiàn)弱引用,比軟引用更弱织鲸,無(wú)論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉被弱引用關(guān)聯(lián)的對(duì)象

(4) 虛引用:通過(guò)PhantomReference實(shí)現(xiàn)虛引用溪胶,最弱的一種引用搂擦,唯一作用是該對(duì)象回收時(shí)收到一個(gè)通知

1.3 對(duì)象的自我拯救 - finalize方法

被虛擬機(jī)判定為不可達(dá)的對(duì)象,還有一次拯救自己的機(jī)會(huì)哗脖。如果對(duì)象在進(jìn)行可達(dá)性分析后發(fā)現(xiàn)沒(méi)有與GC Roots相連接的引用鏈瀑踢,將會(huì)被第一次標(biāo)記,并進(jìn)行一次篩選才避,如果該對(duì)象沒(méi)有重寫finalize()方法橱夭,或者finalize()方法被虛擬機(jī)調(diào)用過(guò),將視為不必執(zhí)行桑逝。

如果被判定為有必要執(zhí)行finalize()方法棘劣,該對(duì)象將會(huì)放入F-Queue隊(duì)列,并在稍后由虛擬機(jī)自動(dòng)創(chuàng)建的楞遏、低優(yōu)先級(jí)的Finalizer線程去執(zhí)行茬暇,finalize()方法是對(duì)象逃脫死亡的最后一次機(jī)會(huì),如果對(duì)象在finalize()方法中重新和引用鏈建立連接寡喝,就可避免被回收糙俗。finalize()方法只會(huì)被系統(tǒng)自動(dòng)調(diào)用一次

1.4 方法區(qū)(永久代)的回收

(1) gc主要回收兩部分內(nèi)容:廢棄常量和無(wú)用的類≡蓿回收廢棄常量和回收堆中的對(duì)象類似巧骚。判定一個(gè)類是否無(wú)用,需同時(shí)滿足3個(gè)條件:一是該類的所有實(shí)例都被回收格二,二是加載該類的ClassLoader已被回收劈彪,三是該類對(duì)應(yīng)的java.lang.Class對(duì)象沒(méi)有在任何地方被引用

(2) HotSpot虛擬機(jī)通過(guò) -Xnoclassgc 參數(shù)進(jìn)行控制是否啟用類卸載功能。在大量使用反射蟋定、動(dòng)態(tài)代理粉臊、CGLib等框架,需要虛擬機(jī)具備類卸載功能驶兜,避免方法區(qū)發(fā)生內(nèi)存溢出

2扼仲、垃圾回收算法

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

(1) 算法分為標(biāo)記和清除兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,然后統(tǒng)一回收有標(biāo)記的對(duì)象

(2) 兩個(gè)不足:一是效率不高抄淑,二是會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片

2.2 復(fù)制(Copying)算法

(1) 新生代分為一個(gè)Eden屠凶,兩個(gè)Survival空間,默認(rèn)比例是8:1肆资〈@ⅲ回收時(shí),將Eden和一個(gè)Survival的存活對(duì)象全部放入到另一個(gè)Survival空間中,最后清理掉剛剛的Eden和Survival空間

(2) 當(dāng)Survival空間不夠時(shí)唉韭,由老年代進(jìn)行內(nèi)存分配擔(dān)保

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

標(biāo)記過(guò)程和“標(biāo)記-清除”算法類似夜涕,不同之處是讓所有存活的對(duì)象向一端移動(dòng),然后直接清理掉邊界以外的對(duì)象

2.4 分代收集(Generational Collection)算法

將堆分為新生代和老年代属愤,新生代對(duì)象存活率低女器,選用復(fù)制算法,老年代存活率高住诸,選用標(biāo)記-清除或標(biāo)記-整理算法

3驾胆、hotspot的算法實(shí)現(xiàn)

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

(1) 可達(dá)性分析時(shí),必須停頓所有java執(zhí)行線程(Stop The World)

(2) HotSpot通過(guò)OopMap記錄對(duì)象引用存放的地址贱呐,類加載完后丧诺,HotSpot把偏移量對(duì)應(yīng)的類型數(shù)據(jù)計(jì)算出來(lái),JIT編譯過(guò)程中奄薇,會(huì)在特定位置記錄下棧和寄存器中哪些位置是引用

3.2 安全點(diǎn)

(1) 程序執(zhí)行時(shí)驳阎,只有到達(dá)安全點(diǎn)才能停頓下來(lái)開始GC

(2) 安全點(diǎn)的選定以“是否讓程序長(zhǎng)時(shí)間執(zhí)行”為標(biāo)準(zhǔn),“長(zhǎng)時(shí)間執(zhí)行”最明顯的特征是指令序列復(fù)用惕艳,如方法調(diào)用搞隐、循環(huán)跳轉(zhuǎn)、異常跳轉(zhuǎn)等

(3) 采用主動(dòng)中斷的方式讓所有線程都跑到最近的安全點(diǎn)上停頓下來(lái)远搪。設(shè)置一個(gè)標(biāo)志劣纲,各個(gè)程序執(zhí)行的時(shí)候輪詢這個(gè)標(biāo)志,發(fā)現(xiàn)中斷標(biāo)志為真時(shí)自己就中斷掛起

3.3 安全區(qū)域

安全區(qū)域是指在代碼片段中谁鳍,引用關(guān)系不會(huì)發(fā)生變化癞季。在這塊區(qū)域任何地方GC都是安全的,可以把Safe Region看做是Safe Point的擴(kuò)展

4倘潜、垃圾回收器

垃圾回收器

上圖展示了7種作用于不同分代的收集器绷柒,如果兩個(gè)收集器之間存在連線,說(shuō)明它們可以搭配使用涮因,所處區(qū)域表示收集器屬于新生代還是老年代废睦。

4.1 Serial收集器

? ? ? ?Serial收集器是一款年輕代的垃圾收集器,使用標(biāo)記-復(fù)制算法养泡。它是一款歷史最悠久的垃圾收集器嗜湃。Serial收集器只能使用一條線程進(jìn)行垃圾收集工作,并且在進(jìn)行垃圾收集的時(shí)候澜掩,所有的工作線程都需要停止工作购披,等待垃圾收集線程完成以后,其他線程才可以繼續(xù)工作肩榕。工作過(guò)程可以簡(jiǎn)單的用下圖來(lái)表示:

4.2 ParNew收集器

(1) ParNew收集器是Serial收集器的多線程版本刚陡,除了多線程外,與Serial相比沒(méi)有太多創(chuàng)新之處

(2) 多線程版本的年輕代收集器中,只有它可以和CMS一起搭配搭配使用

(3) ParNew收集器在單核環(huán)境性能不如Serial收集器(線程交互的開銷)筐乳,默認(rèn)開啟的收集線程數(shù)和CPU數(shù)量相同歌殃,可以使用 -XX:ParallelGCThreads 限定垃圾回收的線程數(shù)

4.3 Parallel Scavenge收集器

(1) 目標(biāo)是達(dá)到一個(gè)可控的吞吐量(Throughput),吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+GC時(shí)間)

(2) 控制吞吐量的兩個(gè)參數(shù):-XX:MaxGCPauseMillis(最大GC停頓時(shí)間)和-XX:GCTimeRatio(設(shè)置吞吐量大小)

(3) -XX:MaxGCPauseMillis允許設(shè)置一個(gè)大于0的毫秒數(shù)哥童,GC停頓時(shí)間短是以犧牲吞吐量和新生代空間換取的

(4) -XX:GCTimeRatio是一個(gè)大于0且小于100的整數(shù)挺份,默認(rèn)值是99,即允許的最大GC時(shí)間1%(即1/(1+99)

(5) -XX:UseAdaptiveSizePolicy贮懈,打開后虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的允許情況收集監(jiān)控信息,動(dòng)態(tài)調(diào)整以提供最適合的停頓時(shí)間或最大的吞吐量优训,該方式稱為GC自適應(yīng)的調(diào)節(jié)

4.4 Serial Old收集器

Serial Old收集器是Serial收集器的老年代版本朵你,同樣是一個(gè)單線程收集器,使用“標(biāo)記-整理”算法揣非,主要用于Client模式下老年代的垃圾收集器抡医。在Server模式下,主要是在JDK1.5版本之前和Parallel Scavenge年輕代收集器配合使用早敬,或者作為CMS收集器的后備收集器

4.5 Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本忌傻,使用多線程和"標(biāo)記-整理"算法,主要是和Parallel Scavenge收集器一起配合(注重吞吐量及CPU資源敏感的場(chǎng)景)搞监,可以實(shí)現(xiàn)對(duì)Java堆內(nèi)存的吞吐量?jī)?yōu)先的垃圾收集策略

4.6 CMS收集器

(1) CMS(Concurrent Mark Sweep)收集器是以最短GC停頓時(shí)間為目標(biāo)的收集器水孩,符合重視服務(wù)響應(yīng)時(shí)間的應(yīng)用

(2) CMS收集器的工作過(guò)程可以分為4個(gè)階段:

初始標(biāo)記(CMS initial mark)階段、并發(fā)標(biāo)記(CMS concurrent mark)階段琐驴、重新標(biāo)記(CMS remark)階段俘种、并發(fā)清除(CMS concurrent sweep)階段

  從圖中可以看出,在這4個(gè)階段中绝淡,初始標(biāo)記和重新標(biāo)記這兩個(gè)階段都只有GC線程在運(yùn)行宙刘,用戶線程會(huì)被停止,所以這兩個(gè)階段會(huì)發(fā)送STW(Stop The World)牢酵。初始標(biāo)記階段的工作是標(biāo)記GC Roots可以直接關(guān)聯(lián)到的對(duì)象悬包,速度很快。并發(fā)標(biāo)記階段馍乙,會(huì)從GC Roots 出發(fā)布近,標(biāo)記處所有可達(dá)的對(duì)象,這個(gè)過(guò)程可能會(huì)花費(fèi)相對(duì)比較長(zhǎng)的時(shí)間潘拨,但是由于在這個(gè)階段吊输,GC線程和用戶線程是可以一起運(yùn)行的,所以即使標(biāo)記過(guò)程比較耗時(shí)铁追,也不會(huì)影響到系統(tǒng)的運(yùn)行季蚂。重新標(biāo)記階段,是對(duì)并發(fā)標(biāo)記期間因用戶程序運(yùn)行而導(dǎo)致標(biāo)記變動(dòng)的那部分記錄進(jìn)行修正,重新標(biāo)記階段耗時(shí)一般比初始標(biāo)記稍長(zhǎng)扭屁,但是遠(yuǎn)小于并發(fā)標(biāo)記階段算谈。最終,會(huì)進(jìn)行并發(fā)清理階段料滥,和并發(fā)標(biāo)記階段類似然眼,并發(fā)清理階段不會(huì)停止系統(tǒng)的運(yùn)行,所以即使相對(duì)耗時(shí)葵腹,也不會(huì)對(duì)系統(tǒng)運(yùn)行產(chǎn)生大的影響高每。

  由于并發(fā)標(biāo)記和并發(fā)清理階段是和應(yīng)用系統(tǒng)一起執(zhí)行的,而初始標(biāo)記和重新標(biāo)記相對(duì)來(lái)說(shuō)耗時(shí)很短践宴,所以可以認(rèn)為CMS收集器在運(yùn)行過(guò)程中鲸匿,是和應(yīng)用程序是并發(fā)執(zhí)行的。由于CMS收集器是一款并發(fā)收集和低停頓的垃圾收集器阻肩,所以CMS收集器也被稱為并發(fā)低停頓收集器带欢。

(3) 不足:一是CMS收集器對(duì)CPU資源非常敏感;二是CMS收集器在處理垃圾收集的過(guò)程中烤惊,可能會(huì)產(chǎn)生浮動(dòng)垃圾乔煞,由于它無(wú)法處理浮動(dòng)垃圾,所以可能會(huì)出現(xiàn)Concurrent Mode Failure問(wèn)題而導(dǎo)致觸發(fā)一次Full GC柒室。所謂的浮動(dòng)垃圾渡贾,是由于CMS收集器的并發(fā)清理階段,清理線程是和用戶線程一起運(yùn)行伦泥,如果在清理過(guò)程中剥啤,用戶線程產(chǎn)生了垃圾對(duì)象,由于過(guò)了標(biāo)記階段不脯,所以這些垃圾對(duì)象就成為了浮動(dòng)垃圾府怯,CMS無(wú)法在當(dāng)前垃圾收集過(guò)程中集中處理這些垃圾對(duì)象;三是它在進(jìn)行垃圾收集時(shí)使用的"標(biāo)記-清除"算法防楷,在進(jìn)行垃圾清理以后牺丙,會(huì)出現(xiàn)很多內(nèi)存碎片,過(guò)多的內(nèi)存碎片會(huì)影響大對(duì)象的分配复局,會(huì)導(dǎo)致即使老年代內(nèi)存還有很多空閑

4.7 G1收集器

為解決CMS算法產(chǎn)生空間碎片和其它一系列的問(wèn)題缺陷冲簿,HotSpot提供了另外一種垃圾回收策略,G1(Garbage First)算法亿昏,通過(guò)參數(shù)-XX:+UseG1GC來(lái)啟用峦剔,該算法在JDK 7u4版本被正式推出,官網(wǎng)對(duì)此描述如下:

The Garbage-First (G1) collector is a server-style garbage collector, targeted for multi-processor machines with large memories. It meets garbage collection (GC) pause time goals with a high probability, while achieving high throughput. The G1 garbage collector is fully supported in Oracle JDK 7 update 4 and later releases. The G1 collector is designed for applications that:

1.Can operate concurrently with applications threads like the CMS collector.

2.Compact free space without lengthy GC induced pause times.

3.Need more predictable GC pause durations.

4.Do not want to sacrifice a lot of throughput performance.

5.Do not require a much larger Java heap.

在G1算法中角钩,堆內(nèi)存被劃分為多個(gè)大小相等的內(nèi)存塊(Region)吝沫,每個(gè)Region是邏輯連續(xù)的一段內(nèi)存呻澜,結(jié)構(gòu)如下:

每個(gè)Region被標(biāo)記了E、S惨险、O和H羹幸,說(shuō)明每個(gè)Region在運(yùn)行時(shí)都充當(dāng)了一種角色,其中H是以往算法中沒(méi)有的辫愉,它代表Humongous栅受,表示這些Region存儲(chǔ)的是巨型對(duì)象(humongous object,H-obj)恭朗,當(dāng)新建對(duì)象大小超過(guò)Region大小一半時(shí)屏镊,直接在新的一個(gè)或多個(gè)連續(xù)Region中分配,并標(biāo)記為H痰腮。

堆內(nèi)存中一個(gè)Region的大小可以通過(guò)-XX:G1HeapRegionSize參數(shù)指定闸衫,大小區(qū)間只能是1M、2M诽嘉、4M、8M弟翘、16M和32M虫腋,總之是2的冪次方。

GC模式:G1中提供了三種模式垃圾回收模式稀余,young gc悦冀、mixed gc 和 full gc,在不同的條件下被觸發(fā)睛琳。

young gc:發(fā)生在年輕代的GC算法盒蟆,一般對(duì)象(除了巨型對(duì)象)都是在eden region中分配內(nèi)存,當(dāng)所有eden region被耗盡無(wú)法申請(qǐng)內(nèi)存時(shí)师骗,就會(huì)觸發(fā)一次young gc历等,這種觸發(fā)機(jī)制和之前的young gc差不多,執(zhí)行完一次young gc辟癌,活躍對(duì)象會(huì)被拷貝到survivor region或者晉升到old region中寒屯,空閑的region會(huì)被放入空閑列表中,等待下次被使用黍少。

參數(shù)含義:-XX:MaxGCPauseMillis設(shè)置G1收集過(guò)程目標(biāo)時(shí)間皆怕,默認(rèn)值200ms瞻佛;-XX:G1NewSizePercent新生代最小值,默認(rèn)值5%;-XX:G1MaxNewSizePercent新生代最大值辜梳,默認(rèn)值60%

mixed gc:當(dāng)越來(lái)越多的對(duì)象晉升到老年代old region時(shí),為了避免堆內(nèi)存被耗盡铲觉,虛擬機(jī)會(huì)觸發(fā)一個(gè)混合的垃圾收集器窝稿,即mixed gc野揪,該算法并不是一個(gè)old gc,除了回收整個(gè)young region传于,還會(huì)回收一部分的old region囱挑,這里需要注意:是一部分老年代,而不是全部老年代沼溜。

mixed gc中有一個(gè)閾值參數(shù)-XX:InitiatingHeapOccupancyPercent平挑,當(dāng)老年代大小占整個(gè)堆大小百分比達(dá)到該閾值時(shí),會(huì)觸發(fā)一次mixed gc系草。mixed gc的執(zhí)行過(guò)程有點(diǎn)類似cms通熄,主要分為以下幾步:

(1) initial mark: 初始標(biāo)記過(guò)程,整個(gè)過(guò)程STW找都,標(biāo)記了從GC Root可達(dá)的對(duì)象

(2) concurrent marking: 并發(fā)標(biāo)記過(guò)程唇辨,整個(gè)過(guò)程gc collector線程與應(yīng)用線程可以并行執(zhí)行,標(biāo)記出GC Root可達(dá)對(duì)象衍生出去的存活對(duì)象能耻,并收集各個(gè)Region的存活對(duì)象信息

(3) remark: 最終標(biāo)記過(guò)程赏枚,整個(gè)過(guò)程STW,標(biāo)記出那些在并發(fā)標(biāo)記過(guò)程中遺漏的晓猛,或者內(nèi)部引用發(fā)生變化的對(duì)象

(4) clean up: 垃圾清除過(guò)程饿幅,如果發(fā)現(xiàn)一個(gè)Region中沒(méi)有存活對(duì)象,則把該Region加入到空閑列表中

full gc:如果對(duì)象內(nèi)存分配速度過(guò)快戒职,mixed gc來(lái)不及回收栗恩,導(dǎo)致老年代被填滿,就會(huì)觸發(fā)一次full gc洪燥,G1的full gc算法就是單線程執(zhí)行的serial old gc磕秤,會(huì)導(dǎo)致異常長(zhǎng)時(shí)間的暫停時(shí)間,需要進(jìn)行不斷的調(diào)優(yōu)捧韵,盡可能的避免full gc

4.8 理解GC日志

33.125:[GC[DefNew:3324K->152K(3712K)市咆,0.0025925secs]3324K->152K(11904K),0.0031680 secs]

100.667:[FullGC[Tenured:0K->210K(10240K)纫版,0.0149142secs]4603K->210K(19456K)床绪,[Perm:2999K->2999K(21248K)],0.0150007 secs][Times:user=0.01 sys=0.00其弊,real=0.02 secs]

最前面的數(shù)字“33.125:”和“100.667:”代表了GC發(fā)生的時(shí)間癞己,這個(gè)數(shù)字的含義是從Java虛擬機(jī)啟動(dòng)以來(lái)經(jīng)過(guò)的秒數(shù)。

GC日志開頭的“[GC”和“[Full GC”說(shuō)明了這次垃圾收集的停頓類型梭伐,而不是用來(lái)區(qū)分新生代GC還是老年代GC的痹雅。如果有“Full”,說(shuō)明這次GC是發(fā)生了Stop-The-World的糊识,例如下面這段新生代收集器ParNew的日志也會(huì)出現(xiàn)“[Full GC”(這一般是因?yàn)槌霈F(xiàn)了分配擔(dān)保失敗之類的問(wèn)題绩社,所以才導(dǎo)致STW)摔蓝。如果是調(diào)用System.gc()方法所觸發(fā)的收集,那么在這里將顯示“[Full GC(System)”愉耙。

[Full GC 283.736:[ParNew:261599K->261599K(261952K)贮尉,0.0000288 secs]

接下來(lái)的“[DefNew”、“[Tenured”朴沿、“[Perm”表示GC發(fā)生的區(qū)域猜谚,這里顯示的區(qū)域名稱與使用的GC收集是密切相關(guān)的,例如上面樣例所使用的Serial收集器中的新生代名為“Default New Generation”赌渣,所以顯示的是“[DefNew”魏铅。

如果是ParNew收集器,新生代名稱就會(huì)變?yōu)椤癧ParNew”坚芜,意為“Parallel New Generation”览芳。

如果采用Parallel Scavenge收集器,那它配套的新生代稱為“PSYoungGen”鸿竖,老年代和永久代同理沧竟,名稱也是由收集器決定的。

后面方括號(hào)內(nèi)部的“3324K->152K(3712K)”含義是“GC前該內(nèi)存區(qū)域已使用容量->GC后該內(nèi)存區(qū)域已使用容量(該內(nèi)存區(qū)域總?cè)萘浚薄?

而在方括號(hào)之外的“3324K->152K(11904K)”表示“GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆總?cè)萘浚薄?/p>

再往后缚忧,“0.0025925 secs”表示該內(nèi)存區(qū)域GC所占用的時(shí)間屯仗,單位是秒。

有的收集器會(huì)給出更具體的時(shí)間數(shù)據(jù)搔谴,如“[Times:user=0.01 sys=0.00,real=0.02 secs]”桩撮,這里面的user敦第、sys和real與Linux的time命令所輸出的時(shí)間含義一致,分別代表用戶態(tài)消耗的CPU時(shí)間店量、內(nèi)核態(tài)消耗的CPU事件和操作從開始到結(jié)束所經(jīng)過(guò)的墻鐘時(shí)間(Wall Clock Time)芜果。

CPU時(shí)間與墻鐘時(shí)間的區(qū)別是,墻鐘時(shí)間包括各種非運(yùn)算的等待耗時(shí)融师,例如等待磁盤I/O右钾、等待線程阻塞,而CPU時(shí)間不包括這些耗時(shí)旱爆。當(dāng)系統(tǒng)有多CPU或者多核的話舀射,多線程操作會(huì)疊加這些CPU時(shí)間,所以讀者看到user或sys時(shí)間超過(guò)real時(shí)間是完全正常的怀伦。

5脆烟、內(nèi)存分配和回收策略

5.1 對(duì)象優(yōu)先在Eden區(qū)分配

一般情況下,對(duì)象在新生代Eden區(qū)分配房待,當(dāng)Eden區(qū)沒(méi)有足夠空間時(shí)邢羔,將發(fā)起一次Minor GC驼抹。-XX:PrintGCDetails可以設(shè)置虛擬機(jī)在發(fā)生GC時(shí)打印內(nèi)存回收日志,并在進(jìn)程退出時(shí)輸出當(dāng)前內(nèi)存各區(qū)域分配情況拜鹤。

5.2 大對(duì)象直接進(jìn)入老年代

大對(duì)象是指需要大量連續(xù)內(nèi)存空間的對(duì)象框冀,如很長(zhǎng)的字符串或數(shù)組。通過(guò)設(shè)置-XX:PretenureSizeThreshold參數(shù)的值敏簿,大于該值的對(duì)象直接在老年代分配

5.3 長(zhǎng)期存活的對(duì)象將進(jìn)入老年代

虛擬機(jī)給每個(gè)對(duì)象定義了年齡明也,每經(jīng)過(guò)一次Minor GC且在新生代存活的對(duì)象,年齡加1极谊,當(dāng)達(dá)到年齡閥值(默認(rèn)15诡右,可以通過(guò)-XX:MaxTenuringThreshold設(shè)置),將會(huì)被晉升到老年代中

5.4 對(duì)象年齡動(dòng)態(tài)判斷

為了更好的適應(yīng)不同程序的內(nèi)存情況轻猖,并不是完全根據(jù)對(duì)象的年齡來(lái)晉升到老年代帆吻,如果Survivor空間中相同年齡所有對(duì)象大小總和大于Survivor空間一半,年齡大于或等于該年齡的對(duì)象將直接進(jìn)入老年代

5.5 空間分配擔(dān)保

在發(fā)生Minor GC之前咙边,虛擬機(jī)會(huì)檢查老年代最大可用連續(xù)空間是否大于新生代所有對(duì)象總空間猜煮,如果成立可以確保Minor GC成功,否則虛擬機(jī)會(huì)查看HandlePromotionFailure是否設(shè)置失敗擔(dān)保败许,如果允許王带,會(huì)檢查老年代最大可用連續(xù)空間是否大于歷次晉升到老年代對(duì)象的平均大小,如果大于市殷,將嘗試進(jìn)行一次Minor GC愕撰,盡管存在風(fēng)險(xiǎn),如果小于醋寝,則進(jìn)行一次Full GC搞挣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市音羞,隨后出現(xiàn)的幾起案子囱桨,更是在濱河造成了極大的恐慌,老刑警劉巖嗅绰,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舍肠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窘面,警方通過(guò)查閱死者的電腦和手機(jī)翠语,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)财边,“玉大人啡专,你說(shuō)我怎么就攤上這事≈迫Γ” “怎么了们童?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵畔况,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我慧库,道長(zhǎng)跷跪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任齐板,我火速辦了婚禮吵瞻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘甘磨。我一直安慰自己橡羞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布济舆。 她就那樣靜靜地躺著卿泽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滋觉。 梳的紋絲不亂的頭發(fā)上签夭,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音椎侠,去河邊找鬼第租。 笑死,一個(gè)胖子當(dāng)著我的面吹牛我纪,可吹牛的內(nèi)容都是我干的慎宾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼浅悉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼璧诵!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起仇冯,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎族操,沒(méi)想到半個(gè)月后苛坚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡色难,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年泼舱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枷莉。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娇昙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笤妙,到底是詐尸還是另有隱情冒掌,我是刑警寧澤噪裕,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站股毫,受9級(jí)特大地震影響膳音,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铃诬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一祭陷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趣席,春花似錦兵志、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至钉寝,卻和暖如春弧呐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嵌纲。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工俘枫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逮走。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓鸠蚪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親师溅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茅信,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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