JVM資料整理

Java 虛擬機(jī)有自己完善的硬件架構(gòu), 如處理器雁乡、堆棧第喳、寄存器等,還具有相應(yīng)的指令系統(tǒng)踱稍。JVM 屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息曲饱,使得 Java 程序只需生成在 Java 虛擬機(jī)上運(yùn)行的目標(biāo)代碼 (字節(jié)碼), 就可以在多種平臺(tái)上不加修改地運(yùn)行。

線程共享區(qū)域?yàn)椋?/p>

1珠月、java堆

2扩淀、方法區(qū)

線程私有區(qū)域?yàn)椋?/p>

3、JVM棧

4桥温、本地方法棧

5引矩、程序計(jì)數(shù)器

各區(qū)域作用:

1、java堆:

java堆是jvm內(nèi)存管理中最大的一塊侵浸,線程共享旺韭。在jvm啟動(dòng)的時(shí)候創(chuàng)建。此區(qū)域唯一目的就是存放對(duì)象實(shí)例掏觉,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存区端。但是隨著JIT編譯器(即時(shí)編譯器)的發(fā)展與逃逸分析技術(shù)的逐漸成熟,棧上分配澳腹、標(biāo)量替換優(yōu)化技術(shù)將會(huì)導(dǎo)致一些微妙變化(對(duì)象可能會(huì)分配到棧上)织盼,所以這種所有對(duì)象都分配在堆上也不是那么絕對(duì)的杨何。

java堆細(xì)分為新生代和老年代,新生代又分為Eden空間沥邻、From Survivor空間危虱、To Survivor空間,新生代中垃圾回收算法為復(fù)制算法唐全,復(fù)制算法是先將內(nèi)存分為連個(gè)部分埃跷,一部分用來放入對(duì)象,而另一部分暫時(shí)不用邮利,當(dāng)使用的一部分內(nèi)存要進(jìn)行垃圾回收的時(shí)候會(huì)將不需要回收的對(duì)象復(fù)制保存在另一個(gè)空間中弥雹,然后再對(duì)使用過的那部分區(qū)域進(jìn)行垃圾回收,這樣雖然效率很高延届,但是很浪費(fèi)空間剪勿,所以一般將新生代分為Eden空間和兩個(gè)Survivor空間,其大小在HotSpot虛擬機(jī)中默認(rèn)比例為8:1:1方庭,這樣在新生代中采用復(fù)制算法回收垃圾效率就很高了厕吉,具體回收過程是將Eden區(qū)域和From Survivor區(qū)域作為對(duì)象的存儲(chǔ)空間,當(dāng)要進(jìn)行垃圾回收的時(shí)候先將這兩個(gè)區(qū)域中不需要回收的對(duì)象復(fù)制保存在To Survivor區(qū)域中二鳄,然后再進(jìn)行垃圾回收赴涵。另外有一點(diǎn)是當(dāng)一個(gè)對(duì)象在Eden區(qū)域和From Survivor區(qū)域中存儲(chǔ)的時(shí)候發(fā)現(xiàn)內(nèi)存不足,這時(shí)會(huì)進(jìn)行內(nèi)存分配擔(dān)保订讼,就是將此對(duì)象直接存入在老年代中髓窜。

關(guān)于對(duì)象的分配:對(duì)象優(yōu)先在Eden區(qū)域分配,大對(duì)象會(huì)直接進(jìn)入老年代欺殿,長期存活的對(duì)象會(huì)進(jìn)入老年代寄纵,這里的長期存活是根據(jù)新生代中的對(duì)象年齡閾值來定義的,對(duì)象剛分配到新生代的時(shí)候年齡為1脖苏,每進(jìn)行一次GC對(duì)象的年齡會(huì)加1程拭,HotSpot中默認(rèn)的閾值是15,也就是說對(duì)象年齡達(dá)到15歲的時(shí)候會(huì)被分配到老年區(qū)棍潘,這個(gè)值是可以通過參數(shù)配置的恃鞋。

在進(jìn)行垃圾回收的時(shí)候新生代GC又叫minor GC,老年代GC可以設(shè)置內(nèi)存容量達(dá)到百分比的多少的時(shí)候進(jìn)行GC亦歉,老年代的GC又叫Full GC恤浪,minor GC時(shí)間短,頻率高肴楷,而Full GC時(shí)間長水由,頻率低。

2赛蔫、方法區(qū)

方法區(qū)又被稱為永久區(qū)砂客,線程共享泥张,是用來存儲(chǔ)已被JVM加載的類信息、常量鞠值、靜態(tài)變量媚创、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。方法區(qū)為堆的一個(gè)邏輯部分齿诉,但是在JDK1.7的HotSpot中已經(jīng)將方法區(qū)中的字符串常量池移出筝野,部分資料顯示JDK1.8已經(jīng)去除了方法區(qū)(不確定)。不過已經(jīng)可以猜測(cè)此區(qū)域?qū)?huì)被本地內(nèi)存逐步取代粤剧。

這個(gè)區(qū)域很少進(jìn)行垃圾回收,回收目標(biāo)主要是針對(duì)常量池的回收和對(duì)類型的卸載挥唠。

3抵恋、JVM棧

JVM棧是線程私有的,它的生命周期與線程相同宝磨。JVM棧描述的是java方法執(zhí)行的內(nèi)存模型弧关,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表唤锉、操作數(shù)棧世囊、動(dòng)態(tài)鏈接、方法出口等信息窿祥。每個(gè)方法從調(diào)用直至執(zhí)行完成的過程株憾,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中入棧到出棧的過程。

局部變量表中存放了編譯期可知的各種基本數(shù)據(jù)類型晒衩、對(duì)象的引用類型嗤瞎。局部變量表中需要的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí)听系,這個(gè)方法需要在幀中分配多大的局部變量空間是完全確定的贝奇,在方法運(yùn)行期間不會(huì)改變局部變量表的大小。

4靠胜、本地方法棧

本地方法棧和JVM棧非常相似掉瞳,它們之間的區(qū)別不過是jvm棧是為執(zhí)行java方法服務(wù),而本地方法棧是為jvm使用到對(duì)的本地方法服務(wù)浪漠。HotSpot虛擬機(jī)中直接把本地方法棧和JVM棧合二為一了陕习。

5、程序計(jì)數(shù)器

程序計(jì)數(shù)器是一塊較小的內(nèi)存空間郑藏,線程私有衡查。它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。在jvm的概念模型里必盖,字節(jié)碼解釋器工作就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令拌牲,分支俱饿、循環(huán)、跳轉(zhuǎn)塌忽、異常處理拍埠、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個(gè)計(jì)數(shù)器來完成。

如果線程正在執(zhí)行的是一個(gè)java方法土居,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的jvm字節(jié)碼指令的地址枣购;如果正在執(zhí)行的是本地方法,這個(gè)計(jì)數(shù)器值則為空擦耀。

總結(jié):

在jvm劃分的內(nèi)存區(qū)域中JVM棧和本地方法椕奕Γ可能會(huì)拋出StackOverflowError異常和OutOfMemoryError異常。java堆和方法區(qū)可能會(huì)拋出OutOfMemoryError異常眷蜓。程序計(jì)數(shù)器中沒有地方規(guī)定會(huì)拋出這兩個(gè)異常分瘾。

2.gc基礎(chǔ)

2.1垃圾收集算法

序號(hào)算法說明優(yōu)/缺點(diǎn)

1引用計(jì)數(shù)法 (Reference Counting)對(duì)于一個(gè)對(duì)象 A,只要有任何一個(gè)對(duì)象引用了 A吁系,則 A 的引用計(jì)數(shù)器就加 1德召。無法處理循環(huán)引用的情況。因此汽纤,在 Java 的垃圾回收器中沒有使用這種算法上岗。

循環(huán)引用問題描述如下:有對(duì)象 A 和對(duì)象 B,對(duì)象 A 中含有對(duì)象 B 的引用蕴坪,對(duì)象 B 中含有對(duì)象 A 的引用肴掷。此時(shí),對(duì)象 A 和對(duì)象 B 的引用計(jì)數(shù)器都不為 0辞嗡。但是在系統(tǒng)中卻不存在任何第 3 個(gè)對(duì)象引用了 A 或 B捆等。也就是說,A 和 B 是應(yīng)該被回收的垃圾對(duì)象续室,但由于垃圾對(duì)象間相互引用栋烤,從而使垃圾回收器無法識(shí)別,引起內(nèi)存泄漏挺狰。

2標(biāo)記-清除算法 (Mark-Sweep)將垃圾回收分為兩個(gè)階段:標(biāo)記階段和清除階段明郭。

一種可行的實(shí)現(xiàn)是,在標(biāo)記階段首先通過根節(jié)點(diǎn)丰泊,標(biāo)記所有從根節(jié)點(diǎn)開始的較大對(duì)象薯定。因此,未被標(biāo)記的對(duì)象就是未被引用的垃圾對(duì)象瞳购。然后话侄,在清除階段,清除所有未被標(biāo)記的對(duì)象。最大的問題是存在大量的空間碎片年堆,因?yàn)榛厥蘸蟮目臻g是不連續(xù)的吞杭。在對(duì)象的堆空間分配過程中,尤其是大對(duì)象的內(nèi)存分配变丧,不連續(xù)的內(nèi)存空間的工作效率要低于連續(xù)的空間芽狗。

3復(fù)制算法 (Copying)將現(xiàn)有的內(nèi)存空間分為兩快,每次只使用其中一塊痒蓬,在垃圾回收時(shí)將正在使用的內(nèi)存中的存活對(duì)象復(fù)制到未被使用的內(nèi)存塊中童擎,之后,清除正在使用的內(nèi)存塊中的所有對(duì)象攻晒,交換兩個(gè)內(nèi)存的角色顾复,完成垃圾回收。

如果系統(tǒng)中的垃圾對(duì)象很多炎辨,復(fù)制算法需要復(fù)制的存活對(duì)象數(shù)量并不會(huì)太大捕透。因此在真正需要垃圾回收的時(shí)刻,復(fù)制算法的效率是很高的碴萧。又由于對(duì)象在垃圾回收過程中統(tǒng)一被復(fù)制到新的內(nèi)存空間中,因此末购,可確逼朴鳎回收后的內(nèi)存空間是沒有碎片的。該算法的缺點(diǎn)是將系統(tǒng)內(nèi)存折半盟榴。

4標(biāo)記-壓縮算法 (Mark-Compact)復(fù)制算法的高效性是建立在存活對(duì)象少曹质、垃圾對(duì)象多的前提下的。這種情況在年輕代經(jīng)常發(fā)生擎场,但是在老年代更常見的情況是大部分對(duì)象都是存活對(duì)象羽德。如果依然使用復(fù)制算法,由于存活的對(duì)象較多迅办,復(fù)制的成本也將很高宅静。

標(biāo)記-壓縮算法是一種老年代的回收算法,它在標(biāo)記-清除算法的基礎(chǔ)上做了一些優(yōu)化站欺。也首先需要從根節(jié)點(diǎn)開始對(duì)所有可達(dá)對(duì)象做一次標(biāo)記姨夹,但之后,它并不簡(jiǎn)單地清理未標(biāo)記的對(duì)象矾策,而是將所有的存活對(duì)象壓縮到內(nèi)存的一端磷账。之后,清理邊界外所有的空間贾虽。這種方法既避免了碎片的產(chǎn)生逃糟,又不需要兩塊相同的內(nèi)存空間,因此,其性價(jià)比比較高绰咽。

5增量算法 (Incremental Collecting)在垃圾回收過程中菇肃,應(yīng)用軟件將處于一種 CPU 消耗很高的狀態(tài)。在這種 CPU 消耗很高的狀態(tài)下剃诅,應(yīng)用程序所有的線程都會(huì)掛起巷送,暫停一切正常的工作,等待垃圾回收的完成矛辕。如果垃圾回收時(shí)間過長笑跛,應(yīng)用程序會(huì)被掛起很久,將嚴(yán)重影響用戶體驗(yàn)或者系統(tǒng)的穩(wěn)定性聊品。

增量算法的基本思想是飞蹂,如果一次性將所有的垃圾進(jìn)行處理,需要造成系統(tǒng)長時(shí)間的停頓翻屈,那么就可以讓垃圾收集線程和應(yīng)用程序線程交替執(zhí)行陈哑。每次,垃圾收集線程只收集一小片區(qū)域的內(nèi)存空間伸眶,接著切換到應(yīng)用程序線程惊窖。依次反復(fù),直到垃圾收集完成厘贼。使用這種方式界酒,由于在垃圾回收過程中,間斷性地還執(zhí)行了應(yīng)用程序代碼嘴秸,所以能減少系統(tǒng)的停頓時(shí)間毁欣。但是,因?yàn)榫€程切換和上下文轉(zhuǎn)換的消耗岳掐,會(huì)使得垃圾回收的總體成本上升凭疮,造成系統(tǒng)吞吐量的下降。

2.2JVM 垃圾回收器分類

根據(jù)垃圾回收對(duì)象的特性串述,不同階段最優(yōu)的方式是使用合適的算法用于本階段的垃圾回收执解。

從不同角度分析垃圾收集器,可以將其分為不同的類型剖煌。

1. 按線程數(shù)分材鹦,可以分為串行垃圾回收器和并行垃圾回收器。串行垃圾回收器一次只使用一個(gè)線程進(jìn)行垃圾回收耕姊;并行垃圾回收器一次將開啟多個(gè)線程同時(shí)進(jìn)行垃圾回收桶唐。在并行能力較強(qiáng)的 CPU 上,使用并行垃圾回收器可以縮短 GC 的停頓時(shí)間茉兰。

2. 按照工作模式分尤泽,可以分為并發(fā)式垃圾回收器和獨(dú)占式垃圾回收器。并發(fā)式垃圾回收器與應(yīng)用程序線程交替工作,以盡可能減少應(yīng)用程序的停頓時(shí)間坯约;獨(dú)占式垃圾回收器 (Stop the world) 一旦運(yùn)行熊咽,就停止應(yīng)用程序中的其他所有線程,直到垃圾回收過程完全結(jié)束闹丐。

3. 按碎片處理方式可分為壓縮式垃圾回收器和非壓縮式垃圾回收器横殴。壓縮式垃圾回收器會(huì)在回收完成后抡蛙,對(duì)存活對(duì)象進(jìn)行壓縮整理庙睡,消除回收后的碎片;非壓縮式的垃圾回收器不進(jìn)行這步操作凰锡。

4. 按工作的內(nèi)存區(qū)間堕花,又可分為新生代垃圾回收器和老年代垃圾回收器文狱。

可以用以下指標(biāo)評(píng)價(jià)一個(gè)垃圾處理器的好壞。

吞吐量:指在應(yīng)用程序的生命周期內(nèi)缘挽,應(yīng)用程序所花費(fèi)的時(shí)間和系統(tǒng)總運(yùn)行時(shí)間的比值瞄崇。系統(tǒng)總運(yùn)行時(shí)間=應(yīng)用程序耗時(shí)+GC 耗時(shí)。如果系統(tǒng)運(yùn)行了 100min壕曼,GC 耗時(shí) 1min苏研,那么系統(tǒng)的吞吐量就是 (100-1)/100=99%。

垃圾回收器負(fù)載:和吞吐量相反腮郊,垃圾回收器負(fù)載指來記回收器耗時(shí)與系統(tǒng)運(yùn)行總時(shí)間的比值楣富。

停頓時(shí)間:指垃圾回收器正在運(yùn)行時(shí),應(yīng)用程序的暫停時(shí)間伴榔。對(duì)于獨(dú)占回收器而言,停頓時(shí)間可能會(huì)比較長庄萎。使用并發(fā)的回收器時(shí)踪少,由于垃圾回收器和應(yīng)用程序交替運(yùn)行,程序的停頓時(shí)間會(huì)變短糠涛,但是援奢,由于其效率很可能不如獨(dú)占垃圾回收器,故系統(tǒng)的吞吐量可能會(huì)較低忍捡。

垃圾回收頻率:指垃圾回收器多長時(shí)間會(huì)運(yùn)行一次集漾。一般來說,對(duì)于固定的應(yīng)用而言砸脊,垃圾回收器的頻率應(yīng)該是越低越好具篇。通常增大堆空間可以有效降低垃圾回收發(fā)生的頻率,但是可能會(huì)增加回收產(chǎn)生的停頓時(shí)間凌埂。

反應(yīng)時(shí)間:指當(dāng)一個(gè)對(duì)象被稱為垃圾后多長時(shí)間內(nèi)驱显,它所占據(jù)的內(nèi)存空間會(huì)被釋放。

堆分配:不同的垃圾回收器對(duì)堆內(nèi)存的分配方式可能是不同的。一個(gè)良好的垃圾收集器應(yīng)該有一個(gè)合理的堆內(nèi)存區(qū)間劃分埃疫。

垃圾收集器種類:

新生代串行收集器

串行收集器主要有兩個(gè)特點(diǎn):第一伏恐,它僅僅使用單線程進(jìn)行垃圾回收;第二栓霜,它獨(dú)占式的垃圾回收翠桦。

在 HotSpot 虛擬機(jī)中,使用-XX:+UseSerialGC參數(shù)可以指定使用新生代串行收集器和老年代串行收集器胳蛮。當(dāng) JVM 在 Client 模式下運(yùn)行時(shí)销凑,它是默認(rèn)的垃圾收集器。

老年代串行收集器

老年代串行收集器使用的是標(biāo)記-壓縮算法鹰霍。

可以嘗試使用以下參數(shù):-XX:+UseSerialGC: 新生代闻鉴、老年代都使用串行回收器。

如果使用-XX:+UseParNewGC 參數(shù)設(shè)置茂洒,表示新生代使用并行收集器孟岛,老年代使用串行收集器

如果使用-XX:+UseParallelGC 參數(shù)設(shè)置,表示新生代和老年代均使用并行回收收集器督勺。

并行收集器

并行收集器是工作在新生代的垃圾收集器渠羞,它只簡(jiǎn)單地將串行回收器多線程化。它的回收策略智哀、算法以及參數(shù)和串行回收器一樣次询。

并行回收器也是獨(dú)占式的回收器,在收集過程中瓷叫,應(yīng)用程序會(huì)全部暫停屯吊。但由于并行回收器使用多線程進(jìn)行垃圾回收,因此摹菠,在并發(fā)能力比較強(qiáng)的 CPU 上盒卸,它產(chǎn)生的停頓時(shí)間要短于串行回收器,而在單 CPU 或者并發(fā)能力較弱的系統(tǒng)中次氨,并行回收器的效果不會(huì)比串行回收器好蔽介,由于多線程的壓力,它的實(shí)際表現(xiàn)很可能比串行回收器差煮寡。

設(shè)置參數(shù)-XX:+UseConcMarkSweepGC可以要求新生代使用并行收集器虹蓄,老年代使用 CMS。

并行收集器工作時(shí)的線程數(shù)量可以使用-XX:ParallelGCThreads 參數(shù)指定幸撕。一般薇组,最好與 CPU 數(shù)量相當(dāng),避免過多的線程數(shù)影響垃圾收集性能杈帐。在默認(rèn)情況下体箕,當(dāng) CPU 數(shù)量小于 8 個(gè)专钉,ParallelGCThreads 的值等于 CPU 數(shù)量,大于 8 個(gè)累铅,ParallelGCThreads 的值等于 3+[5*CPU_Count]/8]跃须。

新生代并行回收 (Parallel Scavenge) 收集器

新生代并行回收收集器也是使用復(fù)制算法的收集器。從表面上看娃兽,它和并行收集器一樣都是多線程菇民、獨(dú)占式的收集器。但是投储,并行回收收集器有一個(gè)重要的特點(diǎn):它非常關(guān)注系統(tǒng)的吞吐量第练。

新生代并行回收收集器可以使用以下參數(shù)啟用:

-XX:+UseParallelGC:新生代使用并行回收收集器,老年代使用串行收集器玛荞。

-XX:+UseParallelOldGC:新生代和老年代都是用并行回收收集器娇掏。

-XX:+MaxGCPauseMills:設(shè)置最大垃圾收集停頓時(shí)間,它的值是一個(gè)大于 0 的整數(shù)勋眯。收集器在工作時(shí)會(huì)調(diào)整 Java 堆大小或者其他一些參數(shù)婴梧,盡可能地把停頓時(shí)間控制在 MaxGCPauseMills 以內(nèi)。如果希望減少停頓時(shí)間客蹋,而把這個(gè)值設(shè)置得很小塞蹭,為了達(dá)到預(yù)期的停頓時(shí)間,JVM 可能會(huì)使用一個(gè)較小的堆 (一個(gè)小堆比一個(gè)大堆回收快)讶坯,而這將導(dǎo)致垃圾回收變得很頻繁番电,從而增加了垃圾回收總時(shí)間,降低了吞吐量辆琅。

-XX:+GCTimeRatio:設(shè)置吞吐量大小漱办,它的值是一個(gè) 0-100 之間的整數(shù)。假設(shè) GCTimeRatio 的值為 n婉烟,那么系統(tǒng)將花費(fèi)不超過 1/(1+n) 的時(shí)間用于垃圾收集洼冻。比如 GCTimeRatio 等于 19,則系統(tǒng)用于垃圾收集的時(shí)間不超過 1/(1+19)=5%隅很。默認(rèn)情況下,它的取值是 99率碾,即不超過 1%的時(shí)間用于垃圾收集叔营。

除此之外,并行回收收集器與并行收集器另一個(gè)不同之處在于所宰,它支持一種自適應(yīng)的 GC 調(diào)節(jié)策略绒尊,使用-XX:+UseAdaptiveSizePolicy 可以打開自適應(yīng) GC 策略。在這種模式下仔粥,新生代的大小婴谱、eden 和 survivor 的比例蟹但、晉升老年代的對(duì)象年齡等參數(shù)會(huì)被自動(dòng)調(diào)整,以達(dá)到在堆大小谭羔、吞吐量和停頓時(shí)間之間的平衡點(diǎn)华糖。在手工調(diào)優(yōu)比較困難的場(chǎng)合,可以直接使用這種自適應(yīng)的方式瘟裸,僅指定虛擬機(jī)的最大堆客叉、目標(biāo)的吞吐量 (GCTimeRatio) 和停頓時(shí)間 (MaxGCPauseMills),讓虛擬機(jī)自己完成調(diào)優(yōu)工作话告。

老年代并行回收收集器

和新生代并行回收收集器一樣兼搏,它也是一種關(guān)注吞吐量的收集器。老年代并行回收收集器使用標(biāo)記-壓縮算法沙郭,JDK1.6 之后開始啟用佛呻、

CMS 收集器

與并行回收收集器不同,CMS 收集器主要關(guān)注于系統(tǒng)停頓時(shí)間病线。CMS 是 Concurrent Mark Sweep 的縮寫吓著,意為并發(fā)標(biāo)記清除,從名稱上可以得知氧苍,它使用的是標(biāo)記-清除算法夜矗,同時(shí)它又是一個(gè)使用多線程并發(fā)回收的垃圾收集器。

CMS 工作時(shí)让虐,主要步驟有:初始標(biāo)記紊撕、并發(fā)標(biāo)記、重新標(biāo)記赡突、并發(fā)清除和并發(fā)重置对扶。其中初始標(biāo)記和重新標(biāo)記是獨(dú)占系統(tǒng)資源的,而并發(fā)標(biāo)記惭缰、并發(fā)清除和并發(fā)重置是可以和用戶線程一起執(zhí)行的浪南。因此,從整體上來說漱受,CMS 收集不是獨(dú)占式的络凿,它可以在應(yīng)用程序運(yùn)行過程中進(jìn)行垃圾回收。

CMS 默認(rèn)啟動(dòng)的線程數(shù)是 (ParallelGCThreads+3)/4),ParallelGCThreads 是新生代并行收集器的線程數(shù)

CMS 收集器不會(huì)等待堆內(nèi)存飽和時(shí)才進(jìn)行垃圾回收昂羡,而是當(dāng)前堆內(nèi)存使用率達(dá)到某一閾值時(shí)絮记,便開始進(jìn)行回收,以確保應(yīng)用程序在 CMS 工作過程中依然有足夠的空間支持應(yīng)用程序運(yùn)行虐先。

這個(gè)回收閾值可以使用-XX:CMSInitiatingOccupancyFraction來指定怨愤,默認(rèn)是 68。即當(dāng)老年代的空間使用率達(dá)到 68%時(shí)蛹批,會(huì)執(zhí)行一次 CMS 回收撰洗。如果應(yīng)用程序的內(nèi)存使用率增長很快篮愉,在 CMS 的執(zhí)行過程中,已經(jīng)出現(xiàn)了內(nèi)存不足的情況差导,此時(shí)试躏,CMS 回收將會(huì)失敗,JVM 將啟動(dòng)老年代串行收集器進(jìn)行垃圾回收柿汛。

G1 收集器 (Garbage First)

G1 收集器的目標(biāo)是作為一款服務(wù)器的垃圾收集器冗酿,因此,它在吞吐量和停頓控制上络断,預(yù)期要優(yōu)于 CMS 收集器裁替。

與 CMS 收集器相比,G1 收集器是基于標(biāo)記-壓縮算法的貌笨。因此弱判,它不會(huì)產(chǎn)生空間碎片,也沒有必要在收集完成后锥惋,進(jìn)行一次獨(dú)占式的碎片整理工作昌腰。G1 收集器還可以進(jìn)行非常精確的停頓控制。它可以讓開發(fā)人員指定當(dāng)停頓時(shí)長為 M 時(shí)膀跌,垃圾回收時(shí)間不超過 N遭商。使用參數(shù)-XX:+UnlockExperimentalVMOptions –XX:+UseG1GC 來啟用 G1 回收器,設(shè)置 G1 回收器的目標(biāo)停頓時(shí)間:-XX:MaxGCPauseMills=20,-XX:GCPauseIntervalMills=200捅伤。

3.虛擬機(jī)&GC 相關(guān)參數(shù)總結(jié)

虛擬機(jī)提供了-XX:+PrintGCDetails參數(shù)打印收集器日志劫流,并且在進(jìn)程退出時(shí)輸出當(dāng)前內(nèi)存各區(qū)域的分配情況。

例如 通過?-Xms20M?-Xmx20M?-Xmn10M這3個(gè)參數(shù)限制java堆大小為20MB丛忆,且不可擴(kuò)展祠汇。其中10MB分配給新生代,剩下的10MB分配給老年代熄诡。

-XX:SurvivorRatio=8?決定了新生代中Eden區(qū)與一個(gè)Survivor區(qū)的比例為8:1可很,即Eden區(qū)=8MB,一個(gè)Survivor=1MB,另一個(gè)Surviveor也為1MB凰浮。

1. 與串行回收器相關(guān)的參數(shù)

-XX:+UseSerialGC:在新生代和老年代使用串行回收器我抠。

-XX:+SuivivorRatio:設(shè)置 eden 區(qū)大小和 survivor 區(qū)大小的比例。

-XX:+PretenureSizeThreshold:設(shè)置大對(duì)象直接進(jìn)入老年代的閾值袜茧。當(dāng)對(duì)象的大小超過這個(gè)值時(shí)屿良,將直接在老年代分配。

-XX:MaxTenuringThreshold:設(shè)置對(duì)象進(jìn)入老年代的年齡的最大值惫周。每一次 Minor GC 后,對(duì)象年齡就加 1康栈。任何大于這個(gè)年齡的對(duì)象递递,一定會(huì)進(jìn)入老年代喷橙。

2. 與并行 GC 相關(guān)的參數(shù)

-XX:+UseParNewGC: 在新生代使用并行收集器。

-XX:+UseParallelOldGC: 老年代使用并行回收收集器登舞。

-XX:ParallelGCThreads:設(shè)置用于垃圾回收的線程數(shù)贰逾。通常情況下可以和 CPU 數(shù)量相等。但在 CPU 數(shù)量比較多的情況下菠秒,設(shè)置相對(duì)較小的數(shù)值也是合理的疙剑。

-XX:MaxGCPauseMills:設(shè)置最大垃圾收集停頓時(shí)間。它的值是一個(gè)大于 0 的整數(shù)践叠。收集器在工作時(shí)言缤,會(huì)調(diào)整 Java 堆大小或者其他一些參數(shù),盡可能地把停頓時(shí)間控制在 MaxGCPauseMills 以內(nèi)禁灼。

-XX:GCTimeRatio:設(shè)置吞吐量大小管挟,它的值是一個(gè) 0-100 之間的整數(shù)。假設(shè) GCTimeRatio 的值為 n弄捕,那么系統(tǒng)將花費(fèi)不超過 1/(1+n) 的時(shí)間用于垃圾收集僻孝。

-XX:+UseAdaptiveSizePolicy:打開自適應(yīng) GC 策略。在這種模式下守谓,新生代的大小穿铆,eden 和 survivor 的比例、晉升老年代的對(duì)象年齡等參數(shù)會(huì)被自動(dòng)調(diào)整斋荞,以達(dá)到在堆大小荞雏、吞吐量和停頓時(shí)間之間的平衡點(diǎn)。

3. 與 CMS 回收器相關(guān)的參數(shù)

-XX:+UseConcMarkSweepGC: 新生代使用并行收集器譬猫,老年代使用 CMS+串行收集器讯檐。

-XX:+ParallelCMSThreads: 設(shè)定 CMS 的線程數(shù)量。

-XX:+CMSInitiatingOccupancyFraction:設(shè)置 CMS 收集器在老年代空間被使用多少后觸發(fā)染服,默認(rèn)為 68%别洪。

-XX:+UseFullGCsBeforeCompaction:設(shè)定進(jìn)行多少次 CMS 垃圾回收后,進(jìn)行一次內(nèi)存壓縮柳刮。

-XX:+CMSClassUnloadingEnabled:允許對(duì)類元數(shù)據(jù)進(jìn)行回收挖垛。

-XX:+CMSParallelRemarkEndable:啟用并行重標(biāo)記。

-XX:CMSInitatingPermOccupancyFraction:當(dāng)永久區(qū)占用率達(dá)到這一百分比后秉颗,啟動(dòng) CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)痢毒。

-XX:UseCMSInitatingOccupancyOnly:表示只在到達(dá)閾值的時(shí)候,才進(jìn)行 CMS 回收蚕甥。

-XX:+CMSIncrementalMode:使用增量模式哪替,比較適合單 CPU。

4. 與 G1 回收器相關(guān)的參數(shù)

-XX:+UseG1GC:使用 G1 回收器菇怀。

-XX:+UnlockExperimentalVMOptions:允許使用實(shí)驗(yàn)性參數(shù)凭舶。

-XX:+MaxGCPauseMills:設(shè)置最大垃圾收集停頓時(shí)間晌块。

-XX:+GCPauseIntervalMills:設(shè)置停頓間隔時(shí)間。

5. 其他參數(shù)

-XX:+DisableExplicitGC: 禁用顯示 GC帅霜。

4.優(yōu)化經(jīng)驗(yàn)總結(jié)

如何將新對(duì)象預(yù)留在年輕代

由于 Full GC 的成本遠(yuǎn)遠(yuǎn)高于 Minor GC匆背,因此某些情況下需要盡可能將對(duì)象分配在年輕代。

雖然在大部分情況下身冀,JVM 會(huì)嘗試在 Eden 區(qū)分配對(duì)象钝尸,但是由于空間緊張等問題,很可能不得不將部分年輕對(duì)象提前向年老代壓縮搂根。因此珍促,在 JVM 參數(shù)調(diào)優(yōu)時(shí)可以為應(yīng)用程序分配一個(gè)合理的年輕代空間,以最大限度避免新對(duì)象直接進(jìn)入年老代的情況發(fā)生兄墅。

a.-Xms20M-Xmx20M-Xmn10M踢星,適當(dāng)增大Xmn大小:-XX:+PrintGCDetails -Xmx20M -Xms20M-Xmn6M

b.一般來說隙咸,Survivor 區(qū)的空間不夠沐悦,或者占用量達(dá)到 50%時(shí),就會(huì)使對(duì)象進(jìn)入年老代 (不管它的年齡有多大)五督;-XX:+PrintGCDetails -Xmx1000M -Xms500M -Xmn100M -XX:SurvivorRatio=8

c.可以嘗試加上-XX:TargetSurvivorRatio=90 參數(shù)藏否,這樣可以提高 from 區(qū)的利用率,使 from 區(qū)使用到 90%時(shí)充包,再將對(duì)象送入年老代

如何讓大對(duì)象進(jìn)入年老代

嘗試在年輕代分配大對(duì)象副签,很可能導(dǎo)致空間不足,為了有足夠的空間容納大對(duì)象基矮,JVM 不得不將年輕代中的年輕對(duì)象挪到年老代淆储。因?yàn)榇髮?duì)象占用空間多,所以可能需要移動(dòng)大量小的年輕對(duì)象進(jìn)入年老代家浇,這對(duì) GC 相當(dāng)不利本砰。

使用參數(shù)-XX:PetenureSizeThreshold 設(shè)置大對(duì)象直接進(jìn)入年老代的閾值。當(dāng)對(duì)象的大小超過這個(gè)值時(shí)钢悲,將直接在年老代分配点额。參數(shù)-XX:PetenureSizeThreshold 只對(duì)串行收集器和年輕代并行收集器有效,并行回收收集器不識(shí)別這個(gè)參數(shù)莺琳。

如果需要將 1MB 以上的對(duì)象直接在年老代分配还棱,設(shè)置-XX:PetenureSizeThreshold=1000000

如何設(shè)置對(duì)象進(jìn)入年老代的年齡

如果對(duì)象在 Eden 區(qū),經(jīng)過一次 GC 后依然存活惭等,則被移動(dòng)到 Survivor 區(qū)中珍手,對(duì)象年齡加 1。以后,如果對(duì)象每經(jīng)過一次 GC 依然存活琳要,則年齡再加 1料扰。當(dāng)對(duì)象年齡達(dá)到閾值時(shí),就移入年老代焙蹭。

閾值的最大值可以通過參數(shù)-XX:MaxTenuringThreshold 來設(shè)置,默認(rèn)值是 15嫂伞。

實(shí)際晉升年老代年齡等于虛擬機(jī)在運(yùn)行時(shí)根據(jù)內(nèi)存使用情況動(dòng)態(tài)計(jì)算所得的年齡與-XX:MaxTenuringThreshold 中較小的那個(gè)孔厉。

穩(wěn)定的 Java 堆 VS 動(dòng)蕩的 Java 堆

獲得一個(gè)穩(wěn)定的堆大小的方法是使-Xms 和-Xmx 的大小一致,即最大堆和最小堆 (初始堆) 一樣.

系統(tǒng)在運(yùn)行時(shí)堆大小理論上是恒定的帖努,穩(wěn)定的堆空間可以減少 GC 的次數(shù)撰豺。

一個(gè)不穩(wěn)定的堆并非毫無用處。穩(wěn)定的堆大小雖然可以減少 GC 次數(shù)拼余,但同時(shí)也增加了每次 GC 的時(shí)間污桦。讓堆大小在一個(gè)區(qū)間中震蕩,在系統(tǒng)不需要使用大內(nèi)存時(shí)匙监,壓縮堆空間凡橱,使 GC 應(yīng)對(duì)一個(gè)較小的堆,可以加快單次 GC 的速度亭姥。

-XX:MinHeapFreeRatio 參數(shù)用來設(shè)置堆空間最小空閑比例稼钩,默認(rèn)值是 40。當(dāng)堆空間的空閑內(nèi)存小于這個(gè)數(shù)值時(shí)达罗,JVM 便會(huì)擴(kuò)展堆空間坝撑。

-XX:MaxHeapFreeRatio 參數(shù)用來設(shè)置堆空間最大空閑比例,默認(rèn)值是 70粮揉。當(dāng)堆空間的空閑內(nèi)存大于這個(gè)數(shù)值時(shí)巡李,便會(huì)壓縮堆空間,得到一個(gè)較小的堆扶认。

當(dāng)-Xmx 和-Xms 相等時(shí)侨拦,-XX:MinHeapFreeRatio 和-XX:MaxHeapFreeRatio 兩個(gè)參數(shù)無效。

在一個(gè)穩(wěn)定的堆中蝠引,堆空間大小始終不變阳谍,每次 GC 時(shí),都要應(yīng)對(duì)一個(gè) 40MB 的空間螃概。因此矫夯,雖然 GC 次數(shù)減小了,但是單次 GC 速度不如一個(gè)震蕩的堆吊洼。

增大吞吐量提升系統(tǒng)性能

吞吐量優(yōu)先的方案將會(huì)盡可能減少系統(tǒng)執(zhí)行垃圾回收的總時(shí)間训貌,故可以考慮關(guān)注系統(tǒng)吞吐量的并行回收收集器。

–Xmx380m –Xms3800m:設(shè)置 Java 堆的最大值和初始值。一般情況下递沪,為了避免堆內(nèi)存的頻繁震蕩豺鼻,導(dǎo)致系統(tǒng)性能下降,我們的做法是設(shè)置最大堆等于最小堆款慨。假設(shè)這里把最小堆減少為最大堆的一半儒飒,即 1900m,那么 JVM 會(huì)盡可能在 1900MB 堆空間中運(yùn)行檩奠,如果這樣桩了,發(fā)生 GC 的可能性就會(huì)比較高;

-Xss128k:減少線程棧的大小埠戳,這樣可以使剩余的系統(tǒng)內(nèi)存支持更多的線程井誉;

-Xmn2g:設(shè)置年輕代區(qū)域大小為 2GB;

–XX:+UseParallelGC:年輕代使用并行垃圾回收收集器整胃。這是一個(gè)關(guān)注吞吐量的收集器颗圣,可以盡可能地減少 GC 時(shí)間。

–XX:ParallelGC-Threads:設(shè)置用于垃圾回收的線程數(shù)屁使,通常情況下在岂,可以設(shè)置和 CPU 數(shù)量相等。但在 CPU 數(shù)量比較多的情況下屋灌,設(shè)置相對(duì)較小的數(shù)值也是合理的洁段;

–XX:+UseParallelOldGC:設(shè)置年老代使用并行回收收集器。

使用非占有的垃圾回收器

為降低應(yīng)用軟件的垃圾回收時(shí)的停頓共郭,首先考慮的是使用關(guān)注系統(tǒng)停頓的 CMS 回收器祠丝,其次,為了減少 Full GC 次數(shù)除嘹,應(yīng)盡可能將對(duì)象預(yù)留在年輕代写半,因?yàn)槟贻p代 Minor GC 的成本遠(yuǎn)遠(yuǎn)小于年老代的 Full GC。

–XX:ParallelGCThreads=20:設(shè)置 20 個(gè)線程進(jìn)行垃圾回收尉咕;

–XX:+UseParNewGC:年輕代使用并行回收器叠蝇;

–XX:+UseConcMarkSweepGC:年老代使用 CMS 收集器降低停頓;

–XX:+SurvivorRatio:設(shè)置 Eden 區(qū)和 Survivor 區(qū)的比例為 8:1年缎。稍大的 Survivor 空間可以提高在年輕代回收生命周期較短的對(duì)象的可能性悔捶,如果 Survivor 不夠大,一些短命的對(duì)象可能直接進(jìn)入年老代单芜,這對(duì)系統(tǒng)來說是不利的蜕该。

–XX:TargetSurvivorRatio=90:設(shè)置 Survivor 區(qū)的可使用率。這里設(shè)置為 90%洲鸠,則允許 90%的 Survivor 空間被使用堂淡。默認(rèn)值是 50%馋缅。故該設(shè)置提高了 Survivor 區(qū)的使用率。當(dāng)存放的對(duì)象超過這個(gè)百分比绢淀,則對(duì)象會(huì)向年老代壓縮萤悴。因此,這個(gè)選項(xiàng)更有助于將對(duì)象留在年輕代皆的。

–XX:MaxTenuringThreshold:設(shè)置年輕對(duì)象晉升到年老代的年齡覆履。默認(rèn)值是 15 次,即對(duì)象經(jīng)過 15 次 Minor GC 依然存活费薄,則進(jìn)入年老代内狗。這里設(shè)置為 31,目的是讓對(duì)象盡可能地保存在年輕代區(qū)域义锥。

4 參數(shù)解析

filterapi項(xiàng)目jetty啟動(dòng)參數(shù)

JVM_ARGS="-server -Dapp.key=com.sankuai.web.meishifilter.filterapi -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Djava.io.tmpdir=/tmp -Djava.net.preferIPv6Addresses=false"

JVM_HEAP="-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+ExplicitGCInvokesConcurrent -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled -XX:+TieredCompilation -XX:CICompilerCount=4"

JVM_GC="-XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"

JVM_SIZE="-Xmx4096m -Xms4096m -Xmn1536m -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M"

序號(hào)JVM_HEAP

參數(shù)說明

1-XX:+UseConcMarkSweepGC新生代使用并行收集器,老年代使用CMS,使用CMS內(nèi)存收集

最新的JVM版本岩灭,當(dāng)使用-XX:+UseConcMarkSweepGC時(shí)拌倍,-XX:UseParNewGC會(huì)自動(dòng)開啟,即年輕代使用多線程并行執(zhí)行垃圾回收噪径。

2-XX:+CMSParallelRemarkEnabledCMS參數(shù)柱恤,降低標(biāo)記停頓

3-XX:+ExplicitGCInvokesConcurrent系統(tǒng)大量使用NIO中的DirectByteBuffer時(shí),需要定期清理本地內(nèi)存找爱。

DirectByteBuffer通過內(nèi)存映射梗顺,使Java進(jìn)程直接訪問與文件相關(guān)聯(lián)的虛擬地址空間,減少了文件拷貝帶來的開銷车摄,提高了文件讀取效率寺谤。這一塊虛擬地址空間并不是分配在jvm堆上,而是分配在native堆上吮播。yong gc不能回收這部分空間变屁,只能通過Full gc順帶進(jìn)行回收,那是因?yàn)镕ull gc時(shí)會(huì)觸發(fā)sun.misc.Cleaner意狠,對(duì)DirectByteBuffer對(duì)象做清理工作粟关。

為了減少fullGC的卡頓現(xiàn)象,有以下幾種解決辦法:

當(dāng)程序中出現(xiàn):

使用了NIO或者NIO框架(Mina/Netty等)

使用了DirectByteBuffer分配字節(jié)緩沖區(qū)

使用了MappedByteBuffer做內(nèi)存映射

最好使用ExplicitGCInvokesConcurrent參數(shù)來替代DisableExplicitGC环戈。需要注意的是ExplicitGCInvokesConcurrent只能配合CMS收集器使用闷板。

關(guān)于堆外內(nèi)存參考堆外內(nèi)存

參考http://blog.csdn.net/aesop_wubo/article/details/38406709

4-XX:CMSInitiatingOccupancyFraction=70CMS 收集器不會(huì)等待堆內(nèi)存飽和時(shí)才進(jìn)行垃圾回收,而是當(dāng)前堆內(nèi)存使用率達(dá)到某一閾值時(shí)院塞,便開始進(jìn)行回收遮晚,以確保應(yīng)用程序在 CMS 工作過程中依然有足夠的空間支持應(yīng)用程序運(yùn)行。

這個(gè)回收閾值可以使用-XX:CMSInitiatingOccupancyFraction 來指定迫悠,默認(rèn)是 68鹏漆。即當(dāng)老年代的空間使用率達(dá)到 68%時(shí),會(huì)執(zhí)行一次 CMS 回收。如果應(yīng)用程序的內(nèi)存使用率增長很快艺玲,在 CMS 的執(zhí)行過程中括蝠,已經(jīng)出現(xiàn)了內(nèi)存不足的情況,此時(shí)饭聚,CMS 回收將會(huì)失敗忌警,JVM 將啟動(dòng)老年代串行收集器進(jìn)行垃圾回收。

5-XX:+UseCMSInitiatingOccupancyOnly我們用-XX+UseCMSInitiatingOccupancyOnly標(biāo)志來命令JVM不基于運(yùn)行時(shí)收集的數(shù)據(jù)來啟動(dòng)CMS垃圾收集周期秒梳。而是法绵,當(dāng)該標(biāo)志被開啟時(shí),JVM通過CMSInitiatingOccupancyFraction的值進(jìn)行每一次CMS收集酪碘,而不僅僅是第一次朋譬。然而,請(qǐng)記住大多數(shù)情況下兴垦,JVM比我們自己能作出更好的垃圾收集決策徙赢。因此,只有當(dāng)我們充足的理由(比如測(cè)試)并且對(duì)應(yīng)用程序產(chǎn)生的對(duì)象的生命周期有深刻的認(rèn)知時(shí)探越,才應(yīng)該使用該標(biāo)志狡赐。

6XX:+CMSPermGenSweepingEnabled相對(duì)于并行收集器,CMS收集器默認(rèn)不會(huì)對(duì)永久代進(jìn)行垃圾回收钦幔。如果希望對(duì)永久代進(jìn)行垃圾回收枕屉,可用設(shè)置標(biāo)志-XX:+CMSClassUnloadingEnabled。在早期JVM版本中鲤氢,要求設(shè)置額外的標(biāo)志-XX:+CMSPermGenSweepingEnabled搀擂。注意,即使沒有設(shè)置這個(gè)標(biāo)志卷玉,一旦永久代耗盡空間也會(huì)嘗試進(jìn)行垃圾回收哥倔,但是收集不會(huì)是并行的,而再一次進(jìn)行Full GC揍庄。

7-XX:+TieredCompilation打開“多層編譯”(tiered compilation)

參考分層編譯 咆蒿。

在該模式下,代碼會(huì)先被解釋器執(zhí)行蚂子,積累到足夠熱度的時(shí)候由client compiler(C1)編譯沃测,然后繼續(xù)積累熱度到一定程度會(huì)進(jìn)一步被server compiler(C2)重新以更高的優(yōu)化程度編譯。

Oracle JDK從JDK 6u25以后的版本支持了多層編譯(-XX:+TieredCompilation)食茎,這個(gè)的好處是之前server都是采用c2高級(jí)編譯的蒂破,會(huì)比較耗時(shí)且要運(yùn)行一段時(shí)間才會(huì)觸發(fā)編譯,而c1編譯是比較輕量的也比較快觸發(fā)别渔,因此在啟用了多層編譯后附迷,可以在啟動(dòng)后更快的讓部分代碼先進(jìn)入編譯模式惧互。(啟動(dòng)使用client模式,啟動(dòng)后使用server模式)

關(guān)于“java啟動(dòng)時(shí)的速度”參考http://hellojava.info/?tag=tieredcompilation

8-XX:CICompilerCount=4編譯線程數(shù)喇伯,server模式默認(rèn)為2

序號(hào)方法備注

1禁用Full gc顯示調(diào)用(-XX:+DisableExplicitGC)容易導(dǎo)致OOM:”如果啟用了-XX:+DisableExplicitGC選項(xiàng)喊儡,在以下情況下會(huì)出現(xiàn)OOM:系統(tǒng)各方面性能良好,無Full gc且DirectByteBuffer所占用的空間大于-Xmx分配的空間稻据。因?yàn)镈irectByteBuffer會(huì)不斷地在native堆分配空間艾猜,它的引用進(jìn)入了old區(qū),old區(qū)保存大量的引用捻悯,而不能被回收匆赃,最終會(huì)導(dǎo)致native堆空間不足。

減少Full gc次數(shù)通過sun.rmi.dgc.server.gcInterval和un.rmi.dgc.client.gcInterval選項(xiàng)調(diào)整Full gc的時(shí)間間隔進(jìn)而減少Full gc次數(shù)今缚,

例如可以使用-Dsun.rmi.dgc.server.gcInterval=7200000與-Dsun.rmi.dgc.client.gcInterval=7200000 選項(xiàng)控制Full gc時(shí)間間隔

降低每次Full gc的時(shí)間通過ExplicitGCInvokesConcurrent選項(xiàng)算柳,可以使用CMS收集器來觸發(fā)Full gc(相比Full gc,CMS收集器會(huì)花費(fèi)更多的時(shí)間姓言,如果對(duì)QPS比較敏感的應(yīng)用應(yīng)降低CMS觸發(fā)的次數(shù))

JVM_GC參數(shù)說明

1-XX:+PrintGCDetails打印收集器日志埠居,并且在進(jìn)程退出時(shí)輸出當(dāng)前內(nèi)存各區(qū)域的分配情況。

2-XX:+PrintHeapAtGC在進(jìn)行GC的前后打印出堆的信息

3-XX:+PrintTenuringDistribution-XX:MaxTenuringThreshold= 設(shè)置熬過年輕代多少次收集后移入老人區(qū)事期,CMS中默認(rèn)為0,熬過第一次GC就轉(zhuǎn)入纸颜,可以用-XX:+PrintTenuringDistribution 查看兽泣。

4-XX:+PrintGCTimeStamps輸出GC的時(shí)間戳(以基準(zhǔn)時(shí)間的形式)

5-XX:+PrintGCDateStamps輸出GC的時(shí)間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

JVM_SIZE

JVM_SIZE

1-Xmx4096mJVM最大可用內(nèi)存

2-Xms4096mJVM最小可用內(nèi)存

3-Xmn1536m年輕代

4-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256MMetaspace(元空間)

移除永久代的工作從JDK1.7就開始了胁孙。JDK1.7中唠倦,存儲(chǔ)在永久代的部分?jǐn)?shù)據(jù)就已經(jīng)轉(zhuǎn)移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中涮较,并沒完全移除稠鼻,譬如符號(hào)引用(Symbols)轉(zhuǎn)移到了native heap;字面量(interned strings)轉(zhuǎn)移到了java heap狂票;類的靜態(tài)變量(class statics)轉(zhuǎn)移到了java heap候齿。

元空間的本質(zhì)和永久代類似,都是對(duì)JVM規(guī)范中方法區(qū)的實(shí)現(xiàn)闺属。不過元空間與永久代之間最大的區(qū)別在于:元空間并不在虛擬機(jī)中慌盯,而是使用本地內(nèi)存。

-XX:MetaspaceSize掂器,初始空間大小亚皂,達(dá)到該值就會(huì)觸發(fā)垃圾收集進(jìn)行類型卸載,同時(shí)GC會(huì)對(duì)該值進(jìn)行調(diào)整:如果釋放了大量的空間国瓮,就適當(dāng)降低該值灭必;如果釋放了很少的空間狞谱,那么在不超過MaxMetaspaceSize時(shí),適當(dāng)提高該值禁漓。

-XX:MaxMetaspaceSize跟衅,最大空間,默認(rèn)是沒有限制的璃饱。

除了上面兩個(gè)指定大小的選項(xiàng)以外与斤,還有兩個(gè)與 GC 相關(guān)的屬性:

-XX:MinMetaspaceFreeRatio,在GC之后荚恶,最小的Metaspace剩余空間容量的百分比撩穿,減少為分配空間所導(dǎo)致的垃圾收集

-XX:MaxMetaspaceFreeRatio,在GC之后谒撼,最大的Metaspace剩余空間容量的百分比食寡,減少為釋放空間所導(dǎo)致的垃圾收集

參考http://www.cnblogs.com/paddix/p/5309550.html

參考:

https://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651478543&idx=1&sn=09c543923b46021e5c98c3e3054a3895&chksm=bd2536708a52bf66507161dc2687a7ba459f88bfc3db16ee09d86076a21d363c637a2c20ee7f&mpshare=1&scene=1&srcid=0521DHsKqvHB6RTj7JgAjGs1&key=c7f559f0373717c2ca4b6b012c3c2897ebbfa793bb5e2fa819b7c4f1a2866fd5687445c9446390e45df66b44c3a1e83828d5bd90df4cada3a15d7ebf360d5bb9da8d1bc3f6cf2cc8704ab3b54f1636eb&ascene=0&uin=MjkwODA1MjAwMQ%3D%3D&devicetype=iMac+MacBookPro11%2C4+OSX+OSX+10.10.5+build(14F2315)&version=12020510&nettype=WIFI&fontScale=100&pass_ticket=Uf1lu7wCiC0%2BivdEwnS1jJzIMRfARsA3I%2FnH3Nulk%2BfaXBcoZP7xiLGP1ACitweI

CMS參數(shù)http://ifeve.com/useful-jvm-flags-part-7-cms-collector/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市廓潜,隨后出現(xiàn)的幾起案子抵皱,更是在濱河造成了極大的恐慌,老刑警劉巖辩蛋,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呻畸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡悼院,警方通過查閱死者的電腦和手機(jī)伤为,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來据途,“玉大人绞愚,你說我怎么就攤上這事∮币剑” “怎么了位衩?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熔萧。 經(jīng)常有香客問我糖驴,道長,這世上最難降的妖魔是什么佛致? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任遂赠,我火速辦了婚禮,結(jié)果婚禮上晌杰,老公的妹妹穿的比我還像新娘跷睦。我一直安慰自己,他們只是感情好肋演,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布抑诸。 她就那樣靜靜地躺著烂琴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜕乡。 梳的紋絲不亂的頭發(fā)上奸绷,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音层玲,去河邊找鬼号醉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辛块,可吹牛的內(nèi)容都是我干的畔派。 我是一名探鬼主播妒蛇,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼解藻,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了纽窟?” 一聲冷哼從身側(cè)響起尘盼,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤憨愉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后卿捎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體配紫,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年午阵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了躺孝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡趟庄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伪很,到底是詐尸還是另有隱情戚啥,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布锉试,位于F島的核電站猫十,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏呆盖。R本人自食惡果不足惜拖云,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望应又。 院中可真熱鬧宙项,春花似錦、人聲如沸株扛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盆繁,卻和暖如春掀淘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背油昂。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工革娄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冕碟。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓拦惋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鸣哀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子架忌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • 原文閱讀 前言 這段時(shí)間懈怠了,罪過我衬! 最近看到有同事也開始用上了微信公眾號(hào)寫博客了叹放,挺好的~給他們點(diǎn)贊,這博客我...
    碼農(nóng)戲碼閱讀 5,961評(píng)論 2 31
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前挠羔,它的class會(huì)被類裝載器裝入方法區(qū)(Permanent區(qū))井仰,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,664評(píng)論 0 7
  • 1.一些概念 1.1.數(shù)據(jù)類型 Java虛擬機(jī)中,數(shù)據(jù)類型可以分為兩類:基本類型和引用類型破加【愣瘢基本類型的變量保存原始...
    落落落落大大方方閱讀 4,538評(píng)論 4 86
  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,366評(píng)論 1 56
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理,因此不免有一些不準(zhǔn)確的地方范舀,同時(shí)不同JDK版本的...
    高廣超閱讀 15,595評(píng)論 3 83