欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

老生常談JVM的內(nèi)存溢出說明及參數(shù)調(diào)整

 更新時(shí)間:2017年03月18日 10:38:23   投稿:jingxian  
下面小編就為大家?guī)硪黄仙U凧VM的內(nèi)存溢出說明及參數(shù)調(diào)整。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
對(duì)于JVM的內(nèi)存寫過的文章已經(jīng)有點(diǎn)多了,而且有點(diǎn)爛了,不過說那么多大多數(shù)在解決OOM的情況,于此,本文就只闡述這個(gè)內(nèi)容,攜帶一些分析和理解和部分?jǐn)U展內(nèi)容,也就是JVM宕機(jī)中的一些問題,OK,下面說下OOM的常見情況:

第一類內(nèi)存溢出,也是大家認(rèn)為最多,第一反應(yīng)認(rèn)為是的內(nèi)存溢出,就是堆棧溢出:

那什么樣的情況就是堆棧溢出呢?當(dāng)你看到下面的關(guān)鍵字的時(shí)候它就是堆棧溢出了:

java.lang.OutOfMemoryError: ......java heap space.....

也就是當(dāng)你看到heap相關(guān)的時(shí)候就肯定是堆棧溢出了,此時(shí)如果代碼沒有問題的情況下,適當(dāng)調(diào)整-Xmx和-Xms是可以避免的,不過一定是代碼沒有問題的前提,為什么會(huì)溢出呢,要么代碼有問題,要么訪問量太多并且每個(gè)訪問的時(shí)間太長或者數(shù)據(jù)太多,導(dǎo)致數(shù)據(jù)釋放不掉,因?yàn)槔厥掌魇且业侥切┦抢拍芑厥?,這里它不會(huì)認(rèn)為這些東西是垃圾,自然不會(huì)去回收了;主意這個(gè)溢出之前,可能系統(tǒng)會(huì)提前先報(bào)錯(cuò)關(guān)鍵字為:

java.lang.OutOfMemoryError:GC over head limit exceeded

這種情況是當(dāng)系統(tǒng)處于高頻的GC狀態(tài),而且回收的效果依然不佳的情況,就會(huì)開始報(bào)這個(gè)錯(cuò)誤,這種情況一般是產(chǎn)生了很多不可以被釋放的對(duì)象,有可能是引用使用不當(dāng)導(dǎo)致,或申請(qǐng)大對(duì)象導(dǎo)致,但是java heap space的內(nèi)存溢出有可能提前不會(huì)報(bào)這個(gè)錯(cuò)誤,也就是可能內(nèi)存就直接不夠?qū)е?,而不是高頻GC.

第二類內(nèi)存溢出,PermGen的溢出,或者PermGen 滿了的提示,你會(huì)看到這樣的關(guān)鍵字:

關(guān)鍵信息為:

java.lang.OutOfMemoryError: PermGen space

原因:系統(tǒng)的代碼非常多或引用的第三方包非常多、或代碼中使用了大量的常量、或通過intern注入常量、或者通過動(dòng)態(tài)代碼加載等方法,導(dǎo)致常量池的膨脹,雖然JDK 1.5以后可以通過設(shè)置對(duì)永久帶進(jìn)行回收,但是我們希望的是這個(gè)地方是不做GC的,它夠用就行,所以一般情況下今年少做類似的操作,所以在面對(duì)這種情況常用的手段是:增加-XX:PermSize和-XX:MaxPermSize的大小。

第三類內(nèi)存溢出:在使用ByteBuffer中的allocateDirect()的時(shí)候會(huì)用到,很多javaNIO的框架中被封裝為其他的方法

溢出關(guān)鍵字:

java.lang.OutOfMemoryError: Direct buffer memory
如果你在直接或間接使用了ByteBuffer中的allocateDirect方法的時(shí)候,而不做clear的時(shí)候就會(huì)出現(xiàn)類似的問題,常規(guī)的引用程序IO輸出存在一個(gè)內(nèi)核態(tài)與用戶態(tài)的轉(zhuǎn)換過程,也就是對(duì)應(yīng)直接內(nèi)存與非直接內(nèi)存,如果常規(guī)的應(yīng)用程序你要將一個(gè)文件的內(nèi)容輸出到客戶端需要通過OS的直接內(nèi)存轉(zhuǎn)換拷貝到程序的非直接內(nèi)存(也就是heap中),然后再輸出到直接內(nèi)存由操作系統(tǒng)發(fā)送出去,而直接內(nèi)存就是由OS和應(yīng)用程序共同管理的,而非直接內(nèi)存可以直接由應(yīng)用程序自己控制的內(nèi)存,jvm垃圾回收不會(huì)回收掉直接內(nèi)存這部分的內(nèi)存,所以要注意了哦。

如果經(jīng)常有類似的操作,可以考慮設(shè)置參數(shù):-XX:MaxDirectMemorySize

第四類內(nèi)存溢出錯(cuò)誤:

溢出關(guān)鍵字:

java.lang.StackOverflowError

這個(gè)參數(shù)直接說明一個(gè)內(nèi)容,就是-Xss太小了,我們申請(qǐng)很多局部調(diào)用的棧針等內(nèi)容是存放在用戶當(dāng)前所持有的線程中的,線程在jdk 1.4以前默認(rèn)是256K,1.5以后是1M,如果報(bào)這個(gè)錯(cuò),只能說明-Xss設(shè)置得太小,當(dāng)然有些廠商的JVM不是這個(gè)參數(shù),本文僅僅針對(duì)Hotspot VM而已;不過在有必要的情況下可以對(duì)系統(tǒng)做一些優(yōu)化,使得-Xss的值是可用的。

第五類內(nèi)存溢出錯(cuò)誤:

溢出關(guān)鍵字:

java.lang.OutOfMemoryError: unable to create new native thread

上面第四種溢出錯(cuò)誤,已經(jīng)說明了線程的內(nèi)存空間,其實(shí)線程基本只占用heap以外的內(nèi)存區(qū)域,也就是這個(gè)錯(cuò)誤說明除了heap以外的區(qū)域,無法為線程分配一塊內(nèi)存區(qū)域了,這個(gè)要么是內(nèi)存本身就不夠,要么heap的空間設(shè)置得太大了,導(dǎo)致了剩余的內(nèi)存已經(jīng)不多了,而由于線程本身要占用內(nèi)存,所以就不夠用了,說明了原因,如何去修改,不用我多說,你懂的。

第六類內(nèi)存溢出:

溢出關(guān)鍵字

java.lang.OutOfMemoryError: request {} byte for {}out of swap

這類錯(cuò)誤一般是由于地址空間不夠而導(dǎo)致。

六大類常見溢出已經(jīng)說明JVM中99%的溢出情況,要逃出這些溢出情況非常困難,除非一些很怪異的故障問題會(huì)發(fā)生,比如由于物理內(nèi)存的硬件問題,導(dǎo)致了code cache的錯(cuò)誤(在由byte code轉(zhuǎn)換為native code的過程中出現(xiàn),但是概率極低),這種情況內(nèi)存 會(huì)被直接crash掉,類似還有swap的頻繁交互在部分系統(tǒng)中會(huì)導(dǎo)致系統(tǒng)直接被crash掉,OS地址空間不夠的話,系統(tǒng)根本無法啟動(dòng),呵呵;JNI的濫用也會(huì)導(dǎo)致一些本地內(nèi)存無法釋放的問題,所以盡量避開JNI;socket連接數(shù)據(jù)打開過多的socket也會(huì)報(bào)類似:IOException: Too many open files等錯(cuò)誤信息。

JNI就不用多說了,盡量少用,除非你的代碼太牛B了,我無話可說,呵呵,這種內(nèi)存如果沒有在被調(diào)用的語言內(nèi)部將內(nèi)存釋放掉(如C語言),那么在進(jìn)程結(jié)束前這些內(nèi)存永遠(yuǎn)釋放不掉,解決辦法只有一個(gè)就是將進(jìn)程kill掉。

另外GC本身是需要內(nèi)存空間的,因?yàn)樵谶\(yùn)算和中間數(shù)據(jù)轉(zhuǎn)換過程中都需要有內(nèi)存,所以你要保證GC的時(shí)候有足夠的內(nèi)存哦,如果沒有的話GC的過程將會(huì)非常的緩慢。

順便這里就提及一些新的CMS GC的內(nèi)容和策略(有點(diǎn)亂,每次寫都很亂,但是能看多少看多少吧):

首先我再寫一次一前博客中的已經(jīng)寫過的內(nèi)容,就是很多參數(shù)沒啥建議值,建議值是自己在現(xiàn)場根據(jù)實(shí)際情況科學(xué)計(jì)算和測試得到的綜合效果,建議值沒有絕對(duì)好的,而且默認(rèn)值很多也是有問題的,因?yàn)椴煌陌姹竞蛷S商都有很大的區(qū)別,默認(rèn)值沒有永久都是一樣的,就像-Xss參數(shù)的變化一樣,要看到你當(dāng)前的java程序heap的大致情況可以這樣看看(以下參數(shù)是隨便設(shè)置的,并不是什么默認(rèn)值):

$sudo jmap -heap `pgrep java`
Attaching to process ID 4280, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 19.1-b02

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 134217728 (128.0MB)
MaxNewSize = 134217728 (128.0MB)
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 134217728 (128.0MB)
MaxPermSize = 268435456 (256.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 85721088 (81.75MB)
used = 22481312 (21.439849853515625MB)
free = 63239776 (60.310150146484375MB)
26.22611602876529% used
From Space:
capacity = 24051712 (22.9375MB)
used = 478488 (0.45632171630859375MB)
free = 23573224 (22.481178283691406MB)
1.9894134770946867% used
To Space:
capacity = 24248320 (23.125MB)
used = 0 (0.0MB)
free = 24248320 (23.125MB)
0.0% used
PS Old Generation
capacity = 939524096 (896.0MB)
used = 16343864 (15.586723327636719MB)
free = 923180232 (880.4132766723633MB)
1.7395896571023124% used
PS Perm Generation
capacity = 134217728 (128.0MB)
used = 48021344 (45.796722412109375MB)
free = 86196384 (82.20327758789062MB)
35.77868938446045% used

付:sudo是需要拿到管理員權(quán)限,如果你的系統(tǒng)權(quán)限很大那么就不需要了,最后的grep java那個(gè)內(nèi)容如果不對(duì),可以直接通過jps或者ps命令將和java相關(guān)的進(jìn)程號(hào)直接寫進(jìn)去,如:java -map 4280,這個(gè)參數(shù)其實(shí)完全可以通過jstat工具來替代,而且看到的效果更加好,這個(gè)參數(shù)在線上應(yīng)用中,盡量少用(尤其是高并發(fā)的應(yīng)用中),可能會(huì)觸發(fā)JVM的bug,導(dǎo)致應(yīng)用掛起;在jvm 1.6u14后可以編寫任意一段程序,然后在運(yùn)行程序的時(shí)候,增加參數(shù)為:-XX:+PrintFlagsFinal來輸出當(dāng)前JVM中運(yùn)行時(shí)的參數(shù)值,或者通過jinfo來查看,jinfo是非常強(qiáng)大的工具,可以對(duì)部分參數(shù)進(jìn)行動(dòng)態(tài)修改,當(dāng)然內(nèi)存相關(guān)的東西是不能修改的,只能增加一些不是很相關(guān)的參數(shù),有關(guān)JVM的工具使用,后續(xù)文章中如果有機(jī)會(huì)我們?cè)賮硖接懀皇潜疚牡闹攸c(diǎn);補(bǔ)充:關(guān)于參數(shù)的默認(rèn)值對(duì)不同的JVM版本、不同的廠商、運(yùn)行于不同的環(huán)境(一般和位數(shù)有關(guān)系)默認(rèn)值會(huì)有區(qū)別。

OK,再說下反復(fù)的一句,沒有必要的話就不要亂設(shè)置參數(shù),參數(shù)不是拿來玩的,默認(rèn)的參數(shù)對(duì)于這門JDK都是有好處的,關(guān)鍵是否適合你的應(yīng)用場景,一般來講你常規(guī)的只需要設(shè)置以下幾個(gè)參數(shù)就可以了:

-server 表示為服務(wù)器端,會(huì)提供很多服務(wù)器端默認(rèn)的配置,如并行回收,而服務(wù)器上一般這個(gè)參數(shù)都是默認(rèn)的,所以都是可以省掉,與之對(duì)應(yīng)的還有一個(gè)-client參數(shù),一般在64位機(jī)器上,JVM是默認(rèn)啟動(dòng)-server參數(shù),也就是默認(rèn)啟動(dòng)并行GC的,但是是ParallelGC而不是ParallelOldGC,兩者算法不同(后面會(huì)簡單說明下),而比較特殊的是windows 32位上默認(rèn)是-client,這兩個(gè)的區(qū)別不僅僅是默認(rèn)的參數(shù)不一樣,在jdk包下的jre包下一般會(huì)包含client和server包,下面分別對(duì)應(yīng)啟動(dòng)的動(dòng)態(tài)鏈接庫,而真正看到的java、javac等相關(guān)命令指示一個(gè)啟動(dòng)導(dǎo)向,它只是根據(jù)命令找到對(duì)應(yīng)的JVM并傳入jvm中進(jìn)行啟動(dòng),也就是看到的java.exe這些文件并不是jvm;說了這么多,最終總結(jié)一下就是,-server和-client就是完全不同的兩套VM,一個(gè)用于桌面應(yīng)用,一個(gè)用于服務(wù)器的。

-Xmx 為Heap區(qū)域的最大值

-Xms 為Heap區(qū)域的初始值,線上環(huán)境需要與-Xmx設(shè)置為一致,否則capacity的值會(huì)來回飄動(dòng),飄得你心曠神怡,你懂的。

-Xss(或-ss) 這個(gè)其實(shí)也是可以默認(rèn)的,如果你真的覺得有設(shè)置的必要,你就改下吧,1.5以后是1M的默認(rèn)大小(指一個(gè)線程的native空間),如果代碼不多,可以設(shè)置小點(diǎn)來讓系統(tǒng)可以接受更大的內(nèi)存。注意,還有一個(gè)參數(shù)是-XX:ThreadStackSize,這兩個(gè)參數(shù)在設(shè)置的過程中如果都設(shè)置是有沖突的,一般按照J(rèn)VM常理來說,誰設(shè)置在后面,就以誰為主,但是最后發(fā)現(xiàn)如果是在1.6以上的版本,-Xss設(shè)置在后面的確都是以-Xss為主,但是要是-XX:ThreadStackSize設(shè)置在后面,主線程還是為-Xss為主,而其它線程以-XX:ThreadStackSize為主,主線程做了一個(gè)特殊判定處理;單獨(dú)設(shè)置都是以本身為主,-Xss不設(shè)置也不會(huì)采用其默認(rèn)值,除非兩個(gè)都不設(shè)置會(huì)采用-Xss的默認(rèn)值。另外這個(gè)參數(shù)針對(duì)于hotspot的vm,在IBM的jvm中,還有一個(gè)參數(shù)為-Xoss,主要原因是IBM在對(duì)棧的處理上有操作數(shù)棧和方法棧等各種不同的棧種類,而hotspot不管是什么棧都放在一個(gè)私有的線程內(nèi)部的,不區(qū)分是什么棧,所以只需要設(shè)置一個(gè)參數(shù),而IBM的J9不是這樣的;有關(guān)棧上的細(xì)節(jié),后續(xù)我們有機(jī)會(huì)專門寫文章來說明。

-XX:PermSize-XX:MaxPermSize兩個(gè)包含了class的裝載的位置,或者說是方法區(qū)(但不是本地方法區(qū)),在Hotspot默認(rèn)情況下為64M,主意全世界的JVM只有hostpot的VM才有Perm的區(qū)域,或者說只有hotspot才有對(duì)用戶可以設(shè)置的這塊區(qū)域,其他的JVM都沒有,其實(shí)并不是沒有這塊區(qū)域,而是這塊區(qū)域沒有讓用戶來設(shè)置,其實(shí)這塊區(qū)域本身也不應(yīng)該讓用戶來設(shè)置,我們也沒有一個(gè)明確的說法這塊空間必須要設(shè)置多大,都是拍腦袋設(shè)置一個(gè)數(shù)字,如果發(fā)布到線上看下如果用得比較多,就再多點(diǎn),如果用的少,就減少點(diǎn),而這塊區(qū)域和性能關(guān)鍵沒有多大關(guān)系,只要能裝下就OK,并且時(shí)不時(shí)會(huì)因?yàn)镻erm不夠而導(dǎo)致Full GC,所以交給開發(fā)者來調(diào)節(jié)這個(gè)參數(shù)不知道是怎么想的;所以O(shè)racle將在新一代JVM中將這個(gè)區(qū)域徹底刪掉,也就是對(duì)用戶透明,G1的如果真正穩(wěn)定起來,以后JVM的啟動(dòng)參數(shù)將會(huì)非常簡單,而且理論上管理再大的內(nèi)存也是沒有問題的,其實(shí)G1(garbage first,一種基于region的垃圾收集回收器)已經(jīng)在hotspot中開始有所試用,不過目前效果不好,還不如CMS呢,所以只是試用,G1已經(jīng)作為ORACLE對(duì)JVM研發(fā)的最高重點(diǎn),CMS自現(xiàn)在最高版本后也不再有新功能(可以修改bug),該項(xiàng)目已經(jīng)進(jìn)行5年,尚未發(fā)布正式版,CMS是四五年前發(fā)布的正式版,但是是最近一兩年才開始穩(wěn)定,而G1的復(fù)雜性將會(huì)遠(yuǎn)遠(yuǎn)超越CMS,所以要真正使用上G1還有待考察,全世界目前只有IBM J9真正實(shí)現(xiàn)了G1論文中提到的思想(論文于05年左右發(fā)表),IBM已經(jīng)將J9應(yīng)用于websphere中,但是并不代表這是全世界最好的jvm,全世界最好的jvm是Azul(無停頓垃圾回收算法和一個(gè)零開銷的診斷/監(jiān)控工具),幾乎可以說這個(gè)jvm是沒有暫停的,在全世界很多頂尖級(jí)的公司使用,不過價(jià)格非常貴,不能直接使用,目前這個(gè)jvm的主導(dǎo)者在研究JRockit,而目前hotspot和JRockit都是Oracle的,所以他們可能會(huì)合并,所以我們應(yīng)該對(duì)JVM的性能充滿信心。

也就是說你常用的情況下只需要設(shè)置4個(gè)參數(shù)就OK了,除非你的應(yīng)用有些特殊,否則不要亂改,那么來看看一些其他情況的參數(shù)吧:

先來看個(gè)不大常用的,就是大家都知道JVM新的對(duì)象應(yīng)該說幾乎百分百的在Eden里面,除非Eden真的裝不下,我們不考慮這種變態(tài)的問題,因?yàn)榫€上環(huán)境Eden區(qū)域都是不小的,來降低GC的次數(shù)以及全局 GC的概率;而JVM習(xí)慣將內(nèi)存按照較為連續(xù)的位置進(jìn)行分配,這樣使得有足夠的內(nèi)存可以被分配,減少碎片,那么對(duì)于內(nèi)存最后一個(gè)位置必然就有大量的征用問題,JVM在高一點(diǎn)的版本里面提出了為每個(gè)線程分配一些私有的區(qū)域來做來解決這個(gè)問題,而1.5后的版本還可以動(dòng)態(tài)管理這些區(qū)域,那么如何自己設(shè)置和查看這些區(qū)域呢,看下英文全稱為:Thread Local Allocation Buffer,簡稱就是:TLAB,即內(nèi)存本地的持有的buffer,設(shè)置參數(shù)有:

-XX:+UseTLAB 啟用這種機(jī)制的意思
-XX:TLABSize=<size in kb> 設(shè)置大小,也就是本地線程中的私有區(qū)域大?。ㄖ挥羞@個(gè)區(qū)域放不下才會(huì)到Eden中去申請(qǐng))。
-XX:+ResizeTLAB 是否啟動(dòng)動(dòng)態(tài)修改

這幾個(gè)參數(shù)在多CPU下非常有用。

-XX:+PrintTLAB 可以輸出TLAB的內(nèi)容。

下面再閑扯些其它的參數(shù):

如果你需要對(duì)Yong區(qū)域進(jìn)行并行回收應(yīng)該如何修改呢?在jdk1.5以后可以使用參數(shù):

-XX:+UseParNewGC

注意: 與它沖突的參數(shù)是:-XX:+UseParallelOldGC-XX:+UseSerialGC,如果需要用這個(gè)參數(shù),又想讓整個(gè)區(qū)域是并行回收的,那么就使用-XX:+UseConcMarkSweepGC參數(shù)來配合,其實(shí)這個(gè)參數(shù)在使用了CMS后,默認(rèn)就會(huì)啟動(dòng)該參數(shù),也就是這個(gè)參數(shù)在CMS GC下是無需設(shè)置的,后面會(huì)提及到這些參數(shù)。

默認(rèn)服務(wù)器上的對(duì)Full并行GC策略為(這個(gè)時(shí)候Yong空間回收的時(shí)候啟動(dòng)PSYong算法,也是并行回收的):

-XX:+UseParallelGC

另外,在jdk1.5后出現(xiàn)一個(gè)新的參數(shù)如下,這個(gè)對(duì)Yong的回收算法和上面一樣,對(duì)Old區(qū)域會(huì)有所區(qū)別,上面對(duì)Old回收的過程中會(huì)做一個(gè)全局的Compact,也就是全局的壓縮操作,而下面的算法是局部壓縮,為什么要局部壓縮呢?是因?yàn)镴VM發(fā)現(xiàn)每次壓縮后再邏輯上數(shù)據(jù)都在Old區(qū)域的左邊位置,申請(qǐng)的時(shí)候從左向右申請(qǐng),那么生命力越長的對(duì)象就一般是靠左的,所以它認(rèn)為左邊的對(duì)象就是生命力很強(qiáng),而且較為密集的,所以它針對(duì)這種情況進(jìn)行部分密集,但是這兩種算法mark階段都是會(huì)暫停的,而且存活的對(duì)象越多活著的越多;而ParallelOldGC會(huì)進(jìn)行部分壓縮算法(主意一點(diǎn),最原始的copy算法是不需要經(jīng)過mark階段,因?yàn)橹恍枰业揭粋€(gè)或活著的就只需要做拷貝就可以,而Yong區(qū)域借用了Copy算法,只是唯一的區(qū)別就是傳統(tǒng)的copy算法是采用兩個(gè)相同大小的內(nèi)存來拷貝,浪費(fèi)空間為50%,所以分代的目標(biāo)就是想要實(shí)現(xiàn)很多優(yōu)勢所在,認(rèn)為新生代85%以上的對(duì)象都應(yīng)該是死掉的,所以S0和S1一般并不是很大),該算法為jdk 1.5以后對(duì)于絕大部分應(yīng)用的最佳選擇。

-XX:+UseParallelOldGC

-XX:ParallelGCThread=12:并行回收的線程數(shù),最好根據(jù)實(shí)際情況而定,因?yàn)榫€程多往往存在征用調(diào)度和上下文切換的開銷;而且也并非CPU越多線程數(shù)也可以設(shè)置越大,一般設(shè)置為12就再增加用處也不大,主要是算法本身內(nèi)部的征用會(huì)導(dǎo)致其線程的極限就是這樣。

設(shè)置Yong區(qū)域大?。?/span>

-Xmn Yong區(qū)域的初始值和最大值一樣大

-XX:NewSize-XX:MaxNewSize如果設(shè)置以為一樣大就是和-Xmn,在JRockit中會(huì)動(dòng)態(tài)變化這些參數(shù),根據(jù)實(shí)際情況有可能會(huì)變化出兩個(gè)Yong區(qū)域,或者沒有Yong區(qū)域,有些時(shí)候會(huì)生出來一個(gè)半長命對(duì)象區(qū)域;這里除了這幾個(gè)參數(shù)外,還有一個(gè)參數(shù)是NewRatio是設(shè)置Old/Yong的倍數(shù)的,這幾個(gè)參數(shù)都是有沖突的,服務(wù)器端建議是設(shè)置-Xmn就可以了,如果幾個(gè)參數(shù)全部都有設(shè)置,-Xmn和-XX:NewSize與-XX:MaxNewSize將是誰設(shè)置在后面,以誰的為準(zhǔn),而-XX:NewSize -XX:MaxNewSize與-XX:NewRatio時(shí),那么參數(shù)設(shè)置的結(jié)果可能會(huì)以下這樣的(jdk 1.4.1后):

min(MaxNewSize,max(NewSize, heap/(NewRatio+1)))

-XX:NewRatio為Old區(qū)域?yàn)閅ong的多少倍,間接設(shè)置Yong的大小,1.6中如果使用此參數(shù),則默認(rèn)會(huì)在適當(dāng)時(shí)候被動(dòng)態(tài)調(diào)整,具體請(qǐng)看下面參數(shù)UseAdaptiveSizepollcy 的說明。

三個(gè)參數(shù)不要同時(shí)設(shè)置,因?yàn)槎际窃O(shè)置Yong的大小的。

-XX:SurvivorRatio:該參數(shù)為Eden與兩個(gè)求助空間之一的比例,注意Yong的大小等價(jià)于Eden + S0 + S1,S0和S1的大小是等價(jià)的,這個(gè)參數(shù)為Eden與其中一個(gè)S區(qū)域的大小比例,如參數(shù)為8,那么Eden就占用Yong的80%,而S0和S1分別占用10%。

以前的老版本有一個(gè)參數(shù)為:-XX:InitialSurivivorRatio,如果不做任何設(shè)置,就會(huì)以這個(gè)參數(shù)為準(zhǔn),這個(gè)參數(shù)的默認(rèn)值就是8,不過這個(gè)參數(shù)并不是Eden/Survivor的大小,而是Yong/Survivor,所以所以默認(rèn)值8,代表每一個(gè)S區(qū)域的空間大小為Yong區(qū)域的12.5%而不是10%。另外順便提及一下,每次大家看到GC日志的時(shí)候,GC日志中的每個(gè)區(qū)域的最大值,其中Yong的空間最大值,始終比設(shè)置的Yong空間的大小要小一點(diǎn),大概是小12.5%左右,那是因?yàn)槊看慰捎每臻g為Eden加上一個(gè)Survivor區(qū)域的大小,而不是整個(gè)Yong的大小,因?yàn)榭捎每臻g每次最多是這樣大,兩個(gè)Survivor區(qū)域始終有一塊是空的,所以不會(huì)加上兩個(gè)來計(jì)算。

-XX:MaxTenuringThreshold=15:在正常情況下,新申請(qǐng)的對(duì)象在Yong區(qū)域發(fā)生多少次GC后就會(huì)被移動(dòng)到Old(非正常就是S0或S1放不下或者不太可能出現(xiàn)的Eden都放不下的對(duì)象),這個(gè)參數(shù)一般不會(huì)超過16(因?yàn)橛?jì)數(shù)器從0開始計(jì)數(shù),所以設(shè)置為15的時(shí)候相當(dāng)于生命周期為16)。

要查看現(xiàn)在的這個(gè)值的具體情況,可以使用參數(shù):-XX:+PrintTenuringDistribution

通過上面的jmap應(yīng)該可以看出我的機(jī)器上的MinHeapFreeRatio和MaxHeapFreeRatio分別為40個(gè)70,也就是大家經(jīng)常說的在GC后剩余空間小于40%時(shí)capacity開始增大,而大于70%時(shí)減小,由于我們不希望讓它移動(dòng),所以這兩個(gè)參數(shù)幾乎沒有意義,如果你需要設(shè)置就設(shè)置參數(shù)為:

-XX:MinHeapFreeRatio=40
-XX:MaxHeapFreeRatio=70

JDK 1.6后有一個(gè)動(dòng)態(tài)調(diào)節(jié)板塊的,當(dāng)然如果你的每一個(gè)板塊都是設(shè)置固定值,這個(gè)參數(shù)也沒有用,不過如果是非固定的,建議還是不要?jiǎng)討B(tài)調(diào)整,默認(rèn)是開啟的,建議將其關(guān)掉,參數(shù)為:

-XX:+UseAdaptiveSizepollcy 建議使用-XX:-UseAdaptiveSizepollcy關(guān)掉,為什么當(dāng)你的參數(shù)設(shè)置了NewRatio、Survivor、MaxTenuringThreshold這幾個(gè)參數(shù)如果在啟動(dòng)了動(dòng)態(tài)更新情況下,是無效的,當(dāng)然如果你設(shè)置-Xmn是有效的,但是如果設(shè)置的比例的話,初始化可能會(huì)按照你的參數(shù)去運(yùn)行,不過運(yùn)行過程中會(huì)通過一定的算法動(dòng)態(tài)修改,監(jiān)控中你可能會(huì)發(fā)現(xiàn)這些參數(shù)會(huì)發(fā)生改變,甚至于S0和S1的大小不一樣。

如果啟動(dòng)了這個(gè)參數(shù),又想要跟蹤變化,那么就使用參數(shù):-XX:+PrintAdaptiveSizePolicy

上面已經(jīng)提到,javaNIO中通過Direct內(nèi)存來提高性能,這個(gè)區(qū)域的大小默認(rèn)是64M,在適當(dāng)?shù)膱鼍翱梢栽O(shè)置大一些。

-XX:MaxDirectMemorySize

一個(gè)不太常用的參數(shù):

-XX:+ScavengeBeforeFullGC 默認(rèn)是開啟狀態(tài),在full GC前先進(jìn)行minor GC。

對(duì)于java堆中如果要設(shè)置大頁內(nèi)存,可以通過設(shè)置參數(shù):

付:此參數(shù)必須在操作系統(tǒng)的內(nèi)核支持的基礎(chǔ)上,需要在OS級(jí)別做操作為:

echo 1024 > /proc/sys/vm/nr_hugepages

echo 2147483647 > /proc/sys/kernel/shmmax

-XX:+UseLargePages

-XX:LargePageSizeInBytes

此時(shí)整個(gè)JVM都將在這塊內(nèi)存中,否則全部不在這塊內(nèi)存中。

javaIO的臨時(shí)目錄設(shè)置

-Djava.io.tmpdir

jstack會(huì)去尋找/tmp/hsperfdata_admin下去尋找與進(jìn)程號(hào)相同的文件,32位機(jī)器上是沒有問題的,64為機(jī)器的是有BUG的,在jdk 1.6u23版本中已經(jīng)修復(fù)了這個(gè)bug,如果你遇到這個(gè)問題,就需要升級(jí)JDK了。

還記得上次說的平均晉升大小嗎,在并行GC時(shí),如果平均晉升大小大于old剩余空間,則發(fā)生full GC,那么當(dāng)小于剩余空間時(shí),也就是平均晉升小于剩余空間,但是剩余空間小于eden + 一個(gè)survivor的空間時(shí),此時(shí)就依賴于參數(shù):

-XX:-HandlePromotionFailure

啟動(dòng)該參數(shù)時(shí),上述情況成立就發(fā)生minor gc(YGC),大于則發(fā)生full gc(major gc)。

一般默認(rèn)直接分配的對(duì)象如果大于Eden的一半就會(huì)直接晉升到old區(qū)域,但是也可以通過參數(shù)來指定:

-XX:PretenureSizeThreshold=2m 我個(gè)人不建議使用這個(gè)參數(shù)

也就是當(dāng)申請(qǐng)對(duì)象大于這個(gè)值就會(huì)晉升到old區(qū)域。

傳說中GC時(shí)間的限制,一個(gè)是通過比例限制,一個(gè)是通過最大暫停時(shí)間限制,但是GC時(shí)間能限制么,呵呵,在增量中貌似可以限制,不過不能限制住GC總體的時(shí)間,所以這個(gè)參數(shù)也不是那么關(guān)鍵。

-XX:GCTimeRatio=

-XX:MaxGCPauseMillis

-XX:GCTimeLimit

要看到真正暫停的時(shí)間就一個(gè)是看GCDetail的日志,另一個(gè)是設(shè)置參數(shù)看:

-XX:+PrintGCApplicationStoppedTime

有些人,有些人就是喜歡在代碼里面里頭寫System.gc(),??幔@個(gè)不是測試程序是線上業(yè)務(wù),這樣將會(huì)導(dǎo)致N多的問題,不多說了,你應(yīng)該懂的,不懂的話看下書吧,而RMI是很不聽話的一個(gè)鳥玩意,EJB的框架也是基于RMI寫的,RMI為什么不聽話呢,就是它自己在里面非要搞個(gè)System.gc(),哎,為了放置頻繁的做,頻繁的做,你就將這個(gè)命令的執(zhí)行禁用掉吧,當(dāng)然程序不用改,不然那些EJB都跑步起來了,呵呵:

-XX:+DisableExplicitGC 默認(rèn)是沒有禁用掉,寫成+就是禁用掉的了,但是有些時(shí)候在使用allocateDirect的時(shí)候,很多時(shí)候還真需要System.gc來強(qiáng)制回收這塊資源。

內(nèi)存溢出時(shí)導(dǎo)出溢出的錯(cuò)誤信息:
-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=/home/xieyu/logs/ 這個(gè)參數(shù)指定導(dǎo)出時(shí)的路徑,不然導(dǎo)出的路徑就是虛擬機(jī)的目標(biāo)位置,不好找了,默認(rèn)的文件名是:java_pid<進(jìn)程號(hào)>.hprof,這個(gè)文件可以類似使用jmap -dump:file=....,format=b <pid>來dump類似的內(nèi)容,文件后綴都是hprof,然后下載mat工具進(jìn)行分析即可(不過內(nèi)存有多大dump文件就多大,而本地分析的時(shí)候內(nèi)存也需要那么大,所以很多時(shí)候下載到本地都無法啟動(dòng)是很正常的),后續(xù)文章有機(jī)會(huì)我們來說明這些工具,另外jmap -dump參數(shù)也不要經(jīng)常用,會(huì)導(dǎo)致應(yīng)用掛起哦;另外此參數(shù)只會(huì)在第一次輸出OOM的時(shí)候才會(huì)進(jìn)行堆的dump操作(java heap的溢出是可以繼續(xù)運(yùn)行再運(yùn)行的程序的,至于web應(yīng)用是否服務(wù)要看應(yīng)用服務(wù)器自身如何處理,而c heap區(qū)域的溢出就根本沒有dump的機(jī)會(huì),因?yàn)橹苯泳湾礄C(jī)了,目前系統(tǒng)無法看到c heap的大小以及內(nèi)部變化,要看大小只能間接通過看JVM進(jìn)程的內(nèi)存大?。?strong>top或類似參數(shù)),這個(gè)大小一般會(huì)大于heap+perm的大小,多余的部分基本就可以認(rèn)為是c heap的大小了,而看內(nèi)部變化呢只有google perftools可以達(dá)到這個(gè)目的),如果內(nèi)存過大這個(gè)dump操作將會(huì)非常長,所以hotspot如果以后想管理大內(nèi)存,這塊必須有新的辦法出來。

最后,用dump出來的文件,通過mat分析出來的結(jié)果往往有些時(shí)候難以直接確定到底哪里有問題,可以看到的維度大概有:那個(gè)類使用的內(nèi)存最多,以及每一個(gè)線程使用的內(nèi)存,以及線程內(nèi)部每一個(gè)調(diào)用的類和方法所使用的內(nèi)存,但是很多時(shí)候無法判定到底是程序什么地方調(diào)用了這個(gè)類或者方法,因?yàn)檫@里只能看到最終消耗內(nèi)存的類,但是不知道誰使用了它,一個(gè)辦法是掃描代碼,但是太笨重,而且如果是jar包中調(diào)用了就不好弄了,另一種方法是寫agent,那么就需要相應(yīng)的配合了,但是有一個(gè)非常好的工具就是btrace工具(jdk 1.7貌似還不支持),可以跟蹤到某個(gè)類的某個(gè)方法被那些類中的方法調(diào)用過,那這個(gè)問題就好說了,只要知道開銷內(nèi)存的是哪一個(gè)類,就能知道誰調(diào)用過它,OK,關(guān)于btrace的不是本文重點(diǎn),網(wǎng)上都有,后續(xù)文章有機(jī)會(huì)再探討,
原理:
No performance impact during runtime(無性能影響)
Dumping a –Xmx512m heap
Create a 512MB .hprof file(512M內(nèi)存就dump出512M的空間大?。?br /> JVM is “dead” during dumping(死掉時(shí)dump)
Restarting JVM during this dump will cause unusable .hprof file(重啟導(dǎo)致文件不可用)

注明的NUMA架構(gòu),在JVM中開始支持,當(dāng)然也需要CPU和OS的支持才可以,需要設(shè)置參數(shù)為:

-XX:+UseNUMA 必須在并行GC的基礎(chǔ)上才有的

老年代無法分配區(qū)域的最大等待時(shí)間為(默認(rèn)值為0,但是也不要去動(dòng)它):

-XX:GCExpandToAllocateDelayMillis

讓JVM中所有的set和get方法轉(zhuǎn)換為本地代碼:

-XX:+UseFastAccessorMethods

以時(shí)間戳輸出Heap的利用率

-XX:+PrintHeapUsageOverTime

在64bit的OS上面(其實(shí)一般達(dá)不到57位左右),由于指針會(huì)放大為8個(gè)byte,所以會(huì)導(dǎo)致空間使用增加,當(dāng)然,如果內(nèi)存夠大,就沒有問題,但是如果升級(jí)到64bit系統(tǒng)后,只是想讓內(nèi)存達(dá)到4G或者8G,那么就完全可以通過很多指針壓縮為4byte就OK了,所以在提供以下參數(shù)(本參數(shù)于jdk 1.6u23后使用,并自動(dòng)開啟,所以也不需要你設(shè)置,知道就OK):

-XX:+UseCompressedOops 請(qǐng)注意:這個(gè)參數(shù)默認(rèn)在64bit的環(huán)境下默認(rèn)啟動(dòng),但是如果JVM的內(nèi)存達(dá)到32G后,這個(gè)參數(shù)就會(huì)默認(rèn)為不啟動(dòng),因?yàn)?2G內(nèi)存后,壓縮就沒有多大必要了,要管理那么大的內(nèi)存指針也需要很大的寬度了。

后臺(tái)JIT編譯優(yōu)化啟動(dòng)

-XX:+BackgroundCompilation

如果你要輸出GC的日志以及時(shí)間戳,相關(guān)的參數(shù)有:

-XX:+PrintGCDetails 輸出GC的日志詳情,包含了時(shí)間戳

-XX:+PrintGCTimeStamps 輸出GC的時(shí)間戳信息,按照啟動(dòng)JVM后相對(duì)時(shí)間的每次GC的相對(duì)秒值(毫秒在小數(shù)點(diǎn)后面),也就是每次GC相對(duì)啟動(dòng)JVM啟動(dòng)了多少秒后發(fā)生了這次GC

-XX:+PrintGCDateStamps輸出GC的時(shí)間信息,會(huì)按照系統(tǒng)格式的日期輸出每次GC的時(shí)間

-XX:+PrintGCTaskTimeStamps輸出任務(wù)的時(shí)間戳信息,這個(gè)細(xì)節(jié)上比較復(fù)雜,后續(xù)有文章來探討。

-XX:-TraceClassLoading 跟蹤類的裝載

-XX:-TraceClassUnloading 跟蹤類的卸載

-XX:+PrintHeapAtGC 輸出GC后各個(gè)堆板塊的大小。

將常量信息GC信息輸出到日志文件:

-Xloggc:/home/xieyu/logs/gc.log

現(xiàn)在面對(duì)大內(nèi)存比較流行是是CMS GC(最少1.5才支持),首先明白CMS的全稱是什么,不是傳統(tǒng)意義上的內(nèi)容管理系統(tǒng)(Content Management System)哈,第一次我也沒看懂,它的全稱是:Concurrent Mark Sweep,三個(gè)單詞分別代表并發(fā)、標(biāo)記、清掃(主意這里沒有compact操作,其實(shí)CMS GC的確沒有compact操作),也就是在程序運(yùn)行的同時(shí)進(jìn)行標(biāo)記和清掃工作,至于它的原理前面有提及過,只是有不同的廠商在上面做了一些特殊的優(yōu)化,比如一些廠商在標(biāo)記根節(jié)點(diǎn)的過程中,標(biāo)記完當(dāng)前的根,那么這個(gè)根下面的內(nèi)容就不會(huì)被暫?;謴?fù)運(yùn)行了,而移動(dòng)過程中,通過讀屏障來看這個(gè)內(nèi)存是不是發(fā)生移動(dòng),如果在移動(dòng)稍微停一下,移動(dòng)過去后再使用,hotspot還沒這么厲害,暫停時(shí)間還是挺長的,只是相對(duì)其他的GC策略在面對(duì)大內(nèi)存來講是不錯(cuò)的選擇。

下面看一些CMS的策略(并發(fā)GC總時(shí)間會(huì)比常規(guī)的并行GC長,因?yàn)樗窃谶\(yùn)行時(shí)去做GC,很多資源征用都會(huì)影響其GC的效率,而總體的暫停時(shí)間會(huì)短暫很多很多,其并行線程數(shù)默認(rèn)為:(上面設(shè)置的并行線程數(shù) + 3)/ 4

付:CMS是目前Hotspot管理大內(nèi)存最好的JVM,如果是常規(guī)的JVM,最佳選擇為ParallelOldGC,如果必須要以響應(yīng)時(shí)間為準(zhǔn),則選擇CMS,不過CMS有兩個(gè)隱藏的隱患:

1、CMS GC雖然是并發(fā)且并行運(yùn)行的GC,但是初始化的時(shí)候如果采用默認(rèn)值92%JVM 1.5的白皮書上描述為68%其實(shí)是錯(cuò)誤的,1.6是正確的),就很容易出現(xiàn)問題,因?yàn)?strong>CMS GC僅僅針對(duì)Old區(qū)域,Yong區(qū)域使用ParNew算法,也就是Old的CMS回收和Yong的回收可以同時(shí)進(jìn)行,也就是回收過程中Yong有可能會(huì)晉升對(duì)象Old,并且業(yè)務(wù)也可以同時(shí)運(yùn)行,所以92%基本開始啟動(dòng)CMS GC很有可能old的內(nèi)存就不夠用了,當(dāng)內(nèi)存不夠用的時(shí)候,就啟動(dòng)Full GC,并且這個(gè)Full GC是串行的,所以如果弄的不好,CMS會(huì)比并行GC更加慢,為什么要啟用串行是因?yàn)镃MS GC、并行GC、串行GC的繼承關(guān)系決定的,簡單說就是它沒辦法去調(diào)用并行GC的代碼,細(xì)節(jié)說后續(xù)有文章來細(xì)節(jié)說明),建議這個(gè)值設(shè)置為70%左右吧,不過具體時(shí)間還是自己決定。

2、CMS GC另一個(gè)大的隱患,其實(shí)不看也差不多應(yīng)該清楚,看名字就知道,就是不會(huì)做Compact操作,它最惡心的地方也在這里,所以上面才說一般的應(yīng)用都不使用它,它只有內(nèi)存垃圾非常多,多得無法分配晉升的空間的時(shí)候才會(huì)出現(xiàn)一次compact,但是這個(gè)是Full GC,也就是上面的串行,很恐怖的,所以內(nèi)存不是很大的,不要考慮使用它,而且它的算法十分復(fù)雜。

還有一些小的隱患是:和應(yīng)用一起征用CPU(不過這個(gè)不是大問題,增加CPU即可)、整個(gè)運(yùn)行過程中時(shí)間比并行GC長(這個(gè)也不是大問題,因?yàn)槲覀兏雨P(guān)心暫停時(shí)間而不是運(yùn)行時(shí)間,因?yàn)闀和?huì)影響非常多的業(yè)務(wù))。

啟動(dòng)CMS為全局GC方法(注意這個(gè)參數(shù)也不能上面的并行GC進(jìn)行混淆,Yong默認(rèn)是并行的,上面已經(jīng)說過

-XX:+UseConcMarkSweepGC

在并發(fā)GC下啟動(dòng)增量模式,只能在CMS GC下這個(gè)參數(shù)才有效。

-XX:+CMSIncrementalMode

啟動(dòng)自動(dòng)調(diào)節(jié)duty cycle,即在CMS GC中發(fā)生的時(shí)間比率設(shè)置,也就是說這段時(shí)間內(nèi)最大允許發(fā)生多長時(shí)間的GC工作是可以調(diào)整的。

-XX:+CMSIncrementalPacing

在上面這個(gè)參數(shù)設(shè)定后可以分別設(shè)置以下兩個(gè)參數(shù)(參數(shù)設(shè)置的比率,范圍為0-100):

-XX:CMSIncrementalDutyCycleMin=0
-XX:CMSIncrementalDutyCycle=10

增量GC上還有一個(gè)保護(hù)因子(CMSIncrementalSafetyFactor),不太常用;CMSIncrementalOffset提供增量GC連續(xù)時(shí)間比率的設(shè)置;CMSExpAvgFactor為增量并發(fā)的GC增加權(quán)重計(jì)算。

-XX:CMSIncrementalSafetyFactor=
-XX:CMSIncrementalOffset=
-XX:CMSExpAvgFactor=

是否啟動(dòng)并行CMS GC(默認(rèn)也是開啟的)

-XX:+CMSParallelRemarkEnabled

要單獨(dú)對(duì)CMS GC設(shè)置并行線程數(shù)就設(shè)置(默認(rèn)也不需要設(shè)置):

-XX:ParallelCMSThreads

對(duì)PernGen進(jìn)行垃圾回收:

JDK 1.5在CMS GC基礎(chǔ)上需要設(shè)置參數(shù)(也就是前提是CMS GC才有):

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

1.6以后的版本無需設(shè)置:-XX:+CMSPermGenSweepingEnabled,注意,其實(shí)一直以來Full GC都會(huì)觸發(fā)對(duì)Perm的回收過程,CMS GC需要有一些特殊照顧,雖然VM會(huì)對(duì)這塊區(qū)域回收,但是Perm回收的條件幾乎不太可能實(shí)現(xiàn),首先需要這個(gè)類的classloader必須死掉,才可以將該classloader下所有的class干掉,也就是要么全部死掉,要么全部活著;另外,這個(gè)classloader下的class沒有任何object在使用,這個(gè)也太苛刻了吧,因?yàn)槌R?guī)的對(duì)象申請(qǐng)都是通過系統(tǒng)默認(rèn)的,應(yīng)用服務(wù)器也有自己默認(rèn)的classloader,要讓它死掉可能性不大,如果這都死掉了,系統(tǒng)也應(yīng)該快掛了。

CMS GC因?yàn)槭窃诔绦蜻\(yùn)行時(shí)進(jìn)行GC,不會(huì)暫停,所以不能等到不夠用的時(shí)候才去開啟GC,官方說法是他們的默認(rèn)值是68%,但是可惜的是文檔寫錯(cuò)了,經(jīng)過很多測試和源碼驗(yàn)證這個(gè)參數(shù)應(yīng)該是在92%的時(shí)候被啟動(dòng),雖然還有8%的空間,但是還是很可憐了,當(dāng)CMS發(fā)現(xiàn)內(nèi)存實(shí)在不夠的時(shí)候又回到常規(guī)的并行GC,所以很多人在沒有設(shè)置這個(gè)參數(shù)的時(shí)候發(fā)現(xiàn)CMS GC并沒有神馬優(yōu)勢嘛,和并行GC一個(gè)鳥樣子甚至于更加慢,所以這個(gè)時(shí)候需要設(shè)置參數(shù)(這個(gè)參數(shù)在上面已經(jīng)說過,啟動(dòng)CMS一定要設(shè)置這個(gè)參數(shù)):

-XX:CMSInitiatingOccupancyFraction=70

這樣保證Old的內(nèi)存在使用到70%的時(shí)候,就開始啟動(dòng)CMS了;如果你真的想看看默認(rèn)值,那么就使用參數(shù):-XX:+PrintCMSInitiationStatistics 這個(gè)變量只有JDK 1.6可以使用 1.5不可以,查看實(shí)際值-XX:+PrintCMSStatistics;另外,還可以設(shè)置參數(shù)-XX:CMSInitiatingPermOccupancyFraction來設(shè)置Perm空間達(dá)到多少時(shí)啟動(dòng)CMS GC,不過意義不大。

JDK 1.6以后有些時(shí)候啟動(dòng)CMS GC是根據(jù)計(jì)算代價(jià)進(jìn)行啟動(dòng),也就是不一定按照你指定的參數(shù)來設(shè)置的,如果你不想讓它按照所謂的成本來計(jì)算GC的話,那么你就使用一個(gè)參數(shù):-XX:+UseCMSInitiatingOccupancyOnly,默認(rèn)是false,它就只會(huì)按照你設(shè)置的比率來啟動(dòng)CMS GC了。如果你的程序中有System.gc以及設(shè)置了ExplicitGCInvokesConcurrent在jdk 1.6中,這種情況使用NIO是有可能產(chǎn)生問題的。

啟動(dòng)CMS GC的compation操作,也就是發(fā)生多少次后做一次全局的compaction:

-XX:+UseCMSCompactAtFullCollection

-XX:CMSFullGCsBeforeCompaction:發(fā)生多少次CMS Full GC,這個(gè)參數(shù)最好不要設(shè)置,因?yàn)橐鯿ompaction的話,也就是真正的Full GC是串行的,非常慢,讓它自己去決定什么時(shí)候需要做compaction。

-XX:CMSMaxAbortablePrecleanTime=5000 設(shè)置preclean步驟的超時(shí)時(shí)間,單位為毫秒,preclean為cms gc其中一個(gè)步驟,關(guān)于cms gc步驟比較多,本文就不細(xì)節(jié)探討了。

并行GC在mark階段,可能會(huì)同時(shí)發(fā)生minor GC,old區(qū)域也可能發(fā)生改變,于是并發(fā)GC會(huì)對(duì)發(fā)生了改變的內(nèi)容進(jìn)行remark操作,這個(gè)觸發(fā)的條件是:

-XX:CMSScheduleRemarkEdenSizeThreshold

-XX:CMSScheduleRemarkEdenPenetration

即Eden區(qū)域多大的時(shí)候開始觸發(fā),和eden使用量超過百分比多少的時(shí)候觸發(fā),前者默認(rèn)是2M,后者默認(rèn)是50%。

但是如果長期不做remark導(dǎo)致old做不了,可以設(shè)置超時(shí),這個(gè)超時(shí)默認(rèn)是5秒,可以通過參數(shù):

-XX:CMSMaxAbortablePrecleanTime

-XX:+ExplicitGCInvokesConcurrent 在顯示發(fā)生GC的時(shí)候,允許進(jìn)行并行GC。

-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses 幾乎和上面一樣,只不過多一個(gè)對(duì)Perm區(qū)域的回收而已。

補(bǔ)充:

其實(shí)JVM還有很多的版本,很多的廠商,與其優(yōu)化的原則,隨便舉兩個(gè)例子hotspot在GC中做的一些優(yōu)化(這里不說代碼的編譯時(shí)優(yōu)化或運(yùn)行時(shí)優(yōu)化):

Eden申請(qǐng)的空間對(duì)象由Old區(qū)域的某個(gè)對(duì)象的一個(gè)屬性指向(也就是Old區(qū)域的這個(gè)空間不回收,Eden這塊就沒有必要考慮回收),所以Hotspot在CPU寫上面,做了一個(gè)屏障,當(dāng)發(fā)生賦值語句的時(shí)候(對(duì)內(nèi)存來講賦值就是一種寫操作),如果發(fā)現(xiàn)是一個(gè)新的對(duì)象由Old指向Eden,那么就會(huì)將這個(gè)對(duì)象記錄在一個(gè)卡片機(jī)里面,這個(gè)卡片機(jī)是有很多512字節(jié)的卡片組成,當(dāng)在YGC過程中,就基本不會(huì)去移動(dòng)或者管理這塊對(duì)象(付:這種卡片機(jī)會(huì)在CMS GC的算法中使用,不過和這個(gè)卡片不是放在同一個(gè)地方的,也是CMS GC的關(guān)鍵,對(duì)于CMS GC的算法細(xì)節(jié)描述,后續(xù)文章我們單獨(dú)說明)。

Old區(qū)域?qū)τ谝恍┍容^大的對(duì)象,JVM就不會(huì)去管理個(gè)對(duì)象,也就是compact過程中不會(huì)去移動(dòng)這塊對(duì)象的區(qū)域等等吧。

以上大部分參數(shù)為hotspot的自帶關(guān)于性能的參數(shù),參考版本為JDK 1.5和1.6的版本,很多為個(gè)人經(jīng)驗(yàn)說明,不足以說明所有問題,如果有問題,歡迎探討;另外,JDK的參數(shù)是不是就只有這些呢,肯定并不是,我知道的也不止這些,但是有些覺得沒必要說出來的參數(shù)和一些數(shù)學(xué)運(yùn)算的參數(shù)我就不想給出來了,比如像禁用掉GC的參數(shù)有神馬意義,我們的服務(wù)器要是把這個(gè)禁用掉干個(gè)屁啊,呵呵,做測試還可以用這玩玩,讓它不做GC直接溢出;還有一些什么計(jì)算因子啥的,還有很多復(fù)雜的數(shù)學(xué)運(yùn)算規(guī)則,要是把這個(gè)配置明白了,就太那個(gè)了,而且一般情況下也沒那個(gè)必要,JDK到現(xiàn)在的配置參數(shù)多達(dá)上500個(gè)以上,要知道完的話慢慢看吧,不過意義不大,而且要知道默認(rèn)值最靠譜的是看源碼而不是看文檔,官方文檔也只能保證絕大部是正確的,不能保證所有的是正確的。

本文最后追加在jdk 1.6u 24后通過上面說明的-XX:+PrintFlagsFinal輸出的參數(shù)以及默認(rèn)值(還是那句話,在不同的平臺(tái)上是不一樣的),輸出的參數(shù)如下,可以看看JVM的參數(shù)是相當(dāng)?shù)亩?,參?shù)如此之多,你只需要掌握關(guān)鍵即可,參數(shù)還有很多有沖突的,不要糾結(jié)于每一個(gè)參數(shù)的細(xì)節(jié):

$java -XX:+PrintFlagsFinal

uintx AdaptivePermSizeWeight = 20 {product}
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product}
uintx AdaptiveSizePausePolicy = 0 {product}
uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product}
uintx AdaptiveSizePolicyInitializingSteps = 20 {product}
uintx AdaptiveSizePolicyOutputInterval = 0 {product}
uintx AdaptiveSizePolicyWeight = 10 {product}
uintx AdaptiveSizeThroughPutPolicy = 0 {product}
uintx AdaptiveTimeWeight = 25 {product}
bool AdjustConcurrency = false {product}
bool AggressiveOpts = false {product}
intx AliasLevel = 3 {product}
intx AllocatePrefetchDistance = -1 {product}
intx AllocatePrefetchInstr = 0 {product}
intx AllocatePrefetchLines = 1 {product}
intx AllocatePrefetchStepSize = 16 {product}
intx AllocatePrefetchStyle = 1 {product}
bool AllowJNIEnvProxy = false {product}
bool AllowParallelDefineClass = false {product}
bool AllowUserSignalHandlers = false {product}
bool AlwaysActAsServerClassMachine = false {product}
bool AlwaysCompileLoopMethods = false {product}
intx AlwaysInflate = 0 {product}
bool AlwaysLockClassLoader = false {product}
bool AlwaysPreTouch = false {product}
bool AlwaysRestoreFPU = false {product}
bool AlwaysTenure = false {product}
bool AnonymousClasses = false {product}
bool AssertOnSuspendWaitFailure = false {product}
intx Atomics = 0 {product}
uintx AutoGCSelectPauseMillis = 5000 {product}
intx BCEATraceLevel = 0 {product}
intx BackEdgeThreshold = 100000 {pd product}
bool BackgroundCompilation = true {pd product}
uintx BaseFootPrintEstimate = 268435456 {product}
intx BiasedLockingBulkRebiasThreshold = 20 {product}
intx BiasedLockingBulkRevokeThreshold = 40 {product}
intx BiasedLockingDecayTime = 25000 {product}
intx BiasedLockingStartupDelay = 4000 {product}
bool BindGCTaskThreadsToCPUs = false {product}
bool BlockOffsetArrayUseUnallocatedBlock = false {product}
bool BytecodeVerificationLocal = false {product}
bool BytecodeVerificationRemote = true {product}
intx CICompilerCount = 1 {product}
bool CICompilerCountPerCPU = false {product}
bool CITime = false {product}
bool CMSAbortSemantics = false {product}
uintx CMSAbortablePrecleanMinWorkPerIteration = 100 {product}
intx CMSAbortablePrecleanWaitMillis = 100 {product}
uintx CMSBitMapYieldQuantum = 10485760 {product}
uintx CMSBootstrapOccupancy = 50 {product}
bool CMSClassUnloadingEnabled = false {product}
uintx CMSClassUnloadingMaxInterval = 0 {product}
bool CMSCleanOnEnter = true {product}
bool CMSCompactWhenClearAllSoftRefs = true {product}
uintx CMSConcMarkMultiple = 32 {product}
bool CMSConcurrentMTEnabled = true {product}
uintx CMSCoordinatorYieldSleepCount = 10 {product}
bool CMSDumpAtPromotionFailure = false {product}
uintx CMSExpAvgFactor = 50 {product}
bool CMSExtrapolateSweep = false {product}
uintx CMSFullGCsBeforeCompaction = 0 {product}
uintx CMSIncrementalDutyCycle = 10 {product}
uintx CMSIncrementalDutyCycleMin = 0 {product}
bool CMSIncrementalMode = false {product}
uintx CMSIncrementalOffset = 0 {product}
bool CMSIncrementalPacing = true {product}
uintx CMSIncrementalSafetyFactor = 10 {product}
uintx CMSIndexedFreeListReplenish = 4 {product}
intx CMSInitiatingOccupancyFraction = -1 {product}
intx CMSInitiatingPermOccupancyFraction = -1 {product}
intx CMSIsTooFullPercentage = 98 {product}
double CMSLargeCoalSurplusPercent = {product}
double CMSLargeSplitSurplusPercent = {product}
bool CMSLoopWarn = false {product}
uintx CMSMaxAbortablePrecleanLoops = 0 {product}
intx CMSMaxAbortablePrecleanTime = 5000 {product}
uintx CMSOldPLABMax = 1024 {product}
uintx CMSOldPLABMin = 16 {product}
uintx CMSOldPLABNumRefills = 4 {product}
uintx CMSOldPLABReactivityCeiling = 10 {product}
uintx CMSOldPLABReactivityFactor = 2 {product}
bool CMSOldPLABResizeQuicker = false {product}
uintx CMSOldPLABToleranceFactor = 4 {product}
bool CMSPLABRecordAlways = true {product}
uintx CMSParPromoteBlocksToClaim = 16 {product}
bool CMSParallelRemarkEnabled = true {product}
bool CMSParallelSurvivorRemarkEnabled = true {product}
bool CMSPermGenPrecleaningEnabled = true {product}
uintx CMSPrecleanDenominator = 3 {product}
uintx CMSPrecleanIter = 3 {product}
uintx CMSPrecleanNumerator = 2 {product}
bool CMSPrecleanRefLists1 = true {product}
bool CMSPrecleanRefLists2 = false {product}
bool CMSPrecleanSurvivors1 = false {product}
bool CMSPrecleanSurvivors2 = true {product}
uintx CMSPrecleanThreshold = 1000 {product}
bool CMSPrecleaningEnabled = true {product}
bool CMSPrintChunksInDump = false {product}
bool CMSPrintObjectsInDump = false {product}
uintx CMSRemarkVerifyVariant = 1 {product}
bool CMSReplenishIntermediate = true {product}
uintx CMSRescanMultiple = 32 {product}
uintx CMSRevisitStackSize = 1048576 {product}
uintx CMSSamplingGrain = 16384 {product}
bool CMSScavengeBeforeRemark = false {product}
uintx CMSScheduleRemarkEdenPenetration = 50 {product}
uintx CMSScheduleRemarkEdenSizeThreshold = 2097152 {product}
uintx CMSScheduleRemarkSamplingRatio = 5 {product}
double CMSSmallCoalSurplusPercent = {product}
double CMSSmallSplitSurplusPercent = {product}
bool CMSSplitIndexedFreeListBlocks = true {product}
intx CMSTriggerPermRatio = 80 {product}
intx CMSTriggerRatio = 80 {product}
bool CMSUseOldDefaults = false {product}
intx CMSWaitDuration = 2000 {product}
uintx CMSWorkQueueDrainThreshold = 10 {product}
bool CMSYield = true {product}
uintx CMSYieldSleepCount = 0 {product}
intx CMSYoungGenPerWorker = 16777216 {product}
uintx CMS_FLSPadding = 1 {product}
uintx CMS_FLSWeight = 75 {product}
uintx CMS_SweepPadding = 1 {product}
uintx CMS_SweepTimerThresholdMillis = 10 {product}
uintx CMS_SweepWeight = 75 {product}
bool CheckJNICalls = false {product}
bool ClassUnloading = true {product}
intx ClearFPUAtPark = 0 {product}
bool ClipInlining = true {product}
uintx CodeCacheExpansionSize = 32768 {pd product}
uintx CodeCacheFlushingMinimumFreeSpace = 1536000 {product}
uintx CodeCacheMinimumFreeSpace = 512000 {product}
bool CollectGen0First = false {product}
bool CompactFields = true {product}
intx CompilationPolicyChoice = 0 {product}
intx CompilationRepeat = 0 {C1 product}
ccstrlist CompileCommand = {product}
ccstr CompileCommandFile = {product}
ccstrlist CompileOnly = {product}
intx CompileThreshold = 1500 {pd product}
bool CompilerThreadHintNoPreempt = true {product}
intx CompilerThreadPriority = -1 {product}
intx CompilerThreadStackSize = 0 {pd product}
uintx ConcGCThreads = 0 {product}
bool ConvertSleepToYield = true {pd product}
bool ConvertYieldToSleep = false {product}
bool DTraceAllocProbes = false {product}
bool DTraceMethodProbes = false {product}
bool DTraceMonitorProbes = false {product}
uintx DefaultMaxRAMFraction = 4 {product}
intx DefaultThreadPriority = -1 {product}
intx DeferPollingPageLoopCount = -1 {product}
intx DeferThrSuspendLoopCount = 4000 {product}
bool DeoptimizeRandom = false {product}
bool DisableAttachMechanism = false {product}
bool DisableExplicitGC = false {product}
bool DisplayVMOutputToStderr = false {product}
bool DisplayVMOutputToStdout = false {product}
bool DontCompileHugeMethods = true {product}
bool DontYieldALot = false {pd product}
bool DumpSharedSpaces = false {product}
bool EagerXrunInit = false {product}
intx EmitSync = 0 {product}
uintx ErgoHeapSizeLimit = 0 {product}
ccstr ErrorFile = {product}
bool EstimateArgEscape = true {product}
intx EventLogLength = 2000 {product}
bool ExplicitGCInvokesConcurrent = false {product}
bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false {produ
bool ExtendedDTraceProbes = false {product}
bool FLSAlwaysCoalesceLarge = false {product}
uintx FLSCoalescePolicy = 2 {product}
double FLSLargestBlockCoalesceProximity = {product}
bool FailOverToOldVerifier = true {product}
bool FastTLABRefill = true {product}
intx FenceInstruction = 0 {product}
intx FieldsAllocationStyle = 1 {product}
bool FilterSpuriousWakeups = true {product}
bool ForceFullGCJVMTIEpilogues = false {product}
bool ForceNUMA = false {product}
bool ForceSharedSpaces = false {product}
bool ForceTimeHighResolution = false {product}
intx FreqInlineSize = 325 {pd product}
intx G1ConcRefinementGreenZone = 0 {product}
intx G1ConcRefinementRedZone = 0 {product}
intx G1ConcRefinementServiceIntervalMillis = 300 {product}
uintx G1ConcRefinementThreads = 0 {product}
intx G1ConcRefinementThresholdStep = 0 {product}
intx G1ConcRefinementYellowZone = 0 {product}
intx G1ConfidencePercent = 50 {product}
uintx G1HeapRegionSize = 0 {product}
intx G1MarkRegionStackSize = 1048576 {product}
intx G1RSetRegionEntries = 0 {product}
uintx G1RSetScanBlockSize = 64 {product}
intx G1RSetSparseRegionEntries = 0 {product}
intx G1RSetUpdatingPauseTimePercent = 10 {product}
intx G1ReservePercent = 10 {product}
intx G1SATBBufferSize = 1024 {product}
intx G1UpdateBufferSize = 256 {product}
bool G1UseAdaptiveConcRefinement = true {product}
bool G1UseFixedWindowMMUTracker = false {product}
uintx GCDrainStackTargetSize = 64 {product}
uintx GCHeapFreeLimit = 2 {product}
bool GCLockerInvokesConcurrent = false {product}
bool GCOverheadReporting = false {product}
intx GCOverheadReportingPeriodMS = 100 {product}
intx GCPauseIntervalMillis = 500 {product}
uintx GCTaskTimeStampEntries = 200 {product}
uintx GCTimeLimit = 98 {product}
uintx GCTimeRatio = 99 {product}
ccstr HPILibPath = {product}
bool HandlePromotionFailure = true {product}
uintx HeapBaseMinAddress = 2147483648 {pd product}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx HeapFirstMaximumCompactionCount = 3 {product}
uintx HeapMaximumCompactionInterval = 20 {product}
bool IgnoreUnrecognizedVMOptions = false {product}
uintx InitialCodeCacheSize = 163840 {pd product}
uintx InitialHeapSize := 16777216 {product}
uintx InitialRAMFraction = 64 {product}
uintx InitialSurvivorRatio = 8 {product}
intx InitialTenuringThreshold = 7 {product}
uintx InitiatingHeapOccupancyPercent = 45 {product}
bool Inline = true {product}
intx InlineSmallCode = 1000 {pd product}
intx InterpreterProfilePercentage = 33 {product}
bool JNIDetachReleasesMonitors = true {product}
bool JavaMonitorsInStackTrace = true {product}
intx JavaPriority10_To_OSPriority = -1 {product}
intx JavaPriority1_To_OSPriority = -1 {product}
intx JavaPriority2_To_OSPriority = -1 {product}
intx JavaPriority3_To_OSPriority = -1 {product}
intx JavaPriority4_To_OSPriority = -1 {product}
intx JavaPriority5_To_OSPriority = -1 {product}
intx JavaPriority6_To_OSPriority = -1 {product}
intx JavaPriority7_To_OSPriority = -1 {product}
intx JavaPriority8_To_OSPriority = -1 {product}
intx JavaPriority9_To_OSPriority = -1 {product}
bool LIRFillDelaySlots = false {C1 pd product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx LargePageSizeInBytes = 0 {product}
bool LazyBootClassLoader = true {product}
bool ManagementServer = false {product}
uintx MarkStackSize = 32768 {product}
uintx MarkStackSizeMax = 4194304 {product}
intx MarkSweepAlwaysCompactCount = 4 {product}
uintx MarkSweepDeadRatio = 5 {product}
intx MaxBCEAEstimateLevel = 5 {product}
intx MaxBCEAEstimateSize = 150 {product}
intx MaxDirectMemorySize = -1 {product}
bool MaxFDLimit = true {product}
uintx MaxGCMinorPauseMillis = 4294967295 {product}
uintx MaxGCPauseMillis = 4294967295 {product}
uintx MaxHeapFreeRatio = 70 {product}
uintx MaxHeapSize := 268435456 {product}
intx MaxInlineLevel = 9 {product}
intx MaxInlineSize = 35 {product}
intx MaxJavaStackTraceDepth = 1024 {product}
uintx MaxLiveObjectEvacuationRatio = 100 {product}
uintx MaxNewSize = 4294967295 {product}
uintx MaxPermHeapExpansion = 4194304 {product}
uintx MaxPermSize = 67108864 {pd product}
uint64_t MaxRAM = 1073741824 {pd product}
uintx MaxRAMFraction = 4 {product}
intx MaxRecursiveInlineLevel = 1 {product}
intx MaxTenuringThreshold = 15 {product}
intx MaxTrivialSize = 6 {product}
bool MethodFlushing = true {product}
intx MinCodeCacheFlushingInterval = 30 {product}
uintx MinHeapDeltaBytes = 131072 {product}
uintx MinHeapFreeRatio = 40 {product}
intx MinInliningThreshold = 250 {product}
uintx MinPermHeapExpansion = 262144 {product}
uintx MinRAMFraction = 2 {product}
uintx MinSurvivorRatio = 3 {product}
uintx MinTLABSize = 2048 {product}
intx MonitorBound = 0 {product}
bool MonitorInUseLists = false {product}
bool MustCallLoadClassInternal = false {product}
intx NUMAChunkResizeWeight = 20 {product}
intx NUMAPageScanRate = 256 {product}
intx NUMASpaceResizeRate = 1073741824 {product}
bool NUMAStats = false {product}
intx NativeMonitorFlags = 0 {product}
intx NativeMonitorSpinLimit = 20 {product}
intx NativeMonitorTimeout = -1 {product}
bool NeedsDeoptSuspend = false {pd product}
bool NeverActAsServerClassMachine = true {pd product}
bool NeverTenure = false {product}
intx NewRatio = 2 {product}
uintx NewSize = 1048576 {product}
uintx NewSizeThreadIncrease = 4096 {pd product}
intx NmethodSweepFraction = 4 {product}
uintx OldPLABSize = 1024 {product}
uintx OldPLABWeight = 50 {product}
uintx OldSize = 4194304 {product}
bool OmitStackTraceInFastThrow = true {product}
ccstrlist OnError = {product}
ccstrlist OnOutOfMemoryError = {product}
intx OnStackReplacePercentage = 933 {pd product}
uintx PLABWeight = 75 {product}
bool PSChunkLargeArrays = true {product}
intx ParGCArrayScanChunk = 50 {product}
uintx ParGCDesiredObjsFromOverflowList = 20 {product}
bool ParGCTrimOverflow = true {product}
bool ParGCUseLocalOverflow = false {product}
intx ParallelGCBufferWastePct = 10 {product}
bool ParallelGCRetainPLAB = true {product}
uintx ParallelGCThreads = 0 {product}
bool ParallelGCVerbose = false {product}
uintx ParallelOldDeadWoodLimiterMean = 50 {product}
uintx ParallelOldDeadWoodLimiterStdDev = 80 {product}
bool ParallelRefProcBalancingEnabled = true {product}
bool ParallelRefProcEnabled = false {product}
uintx PausePadding = 1 {product}
intx PerBytecodeRecompilationCutoff = 200 {product}
intx PerBytecodeTrapLimit = 4 {product}
intx PerMethodRecompilationCutoff = 400 {product}
intx PerMethodTrapLimit = 100 {product}
bool PerfAllowAtExitRegistration = false {product}
bool PerfBypassFileSystemCheck = false {product}
intx PerfDataMemorySize = 32768 {product}
intx PerfDataSamplingInterval = 50 {product}
ccstr PerfDataSaveFile = {product}
bool PerfDataSaveToFile = false {product}
bool PerfDisableSharedMem = false {product}
intx PerfMaxStringConstLength = 1024 {product}
uintx PermGenPadding = 3 {product}
uintx PermMarkSweepDeadRatio = 20 {product}
uintx PermSize = 12582912 {pd product}
bool PostSpinYield = true {product}
intx PreBlockSpin = 10 {product}
intx PreInflateSpin = 10 {pd product}
bool PreSpinYield = false {product}
bool PreferInterpreterNativeStubs = false {pd product}
intx PrefetchCopyIntervalInBytes = -1 {product}
intx PrefetchFieldsAhead = -1 {product}
intx PrefetchScanIntervalInBytes = -1 {product}
bool PreserveAllAnnotations = false {product}
uintx PreserveMarkStackSize = 1024 {product}
uintx PretenureSizeThreshold = 0 {product}
bool PrintAdaptiveSizePolicy = false {product}
bool PrintCMSInitiationStatistics = false {product}
intx PrintCMSStatistics = 0 {product}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintCommandLineFlags = false {product}
bool PrintCompilation = false {product}
bool PrintConcurrentLocks = false {manageable}
intx PrintFLSCensus = 0 {product}
intx PrintFLSStatistics = 0 {product}
bool PrintFlagsFinal := true {product}
bool PrintFlagsInitial = false {product}
bool PrintGC = false {manageable}
bool PrintGCApplicationConcurrentTime = false {product}
bool PrintGCApplicationStoppedTime = false {product}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCTaskTimeStamps = false {product}
bool PrintGCTimeStamps = false {manageable}
bool PrintHeapAtGC = false {product rw}
bool PrintHeapAtGCExtended = false {product rw}
bool PrintHeapAtSIGBREAK = true {product}
bool PrintJNIGCStalls = false {product}
bool PrintJNIResolving = false {product}
bool PrintOldPLAB = false {product}
bool PrintPLAB = false {product}
bool PrintParallelOldGCPhaseTimes = false {product}
bool PrintPromotionFailure = false {product}
bool PrintReferenceGC = false {product}
bool PrintRevisitStats = false {product}
bool PrintSafepointStatistics = false {product}
intx PrintSafepointStatisticsCount = 300 {product}
intx PrintSafepointStatisticsTimeout = -1 {product}
bool PrintSharedSpaces = false {product}
bool PrintTLAB = false {product}
bool PrintTenuringDistribution = false {product}
bool PrintVMOptions = false {product}
bool PrintVMQWaitTime = false {product}
uintx ProcessDistributionStride = 4 {product}
bool ProfileInterpreter = false {pd product}
bool ProfileIntervals = false {product}
intx ProfileIntervalsTicks = 100 {product}
intx ProfileMaturityPercentage = 20 {product}
bool ProfileVM = false {product}
bool ProfilerPrintByteCodeStatistics = false {product}
bool ProfilerRecordPC = false {product}
uintx PromotedPadding = 3 {product}
intx QueuedAllocationWarningCount = 0 {product}
bool RangeCheckElimination = true {product}
intx ReadPrefetchInstr = 0 {product}
intx ReadSpinIterations = 100 {product}
bool ReduceSignalUsage = false {product}
intx RefDiscoveryPolicy = 0 {product}
bool ReflectionWrapResolutionErrors = true {product}
bool RegisterFinalizersAtInit = true {product}
bool RelaxAccessControlCheck = false {product}
bool RequireSharedSpaces = false {product}
uintx ReservedCodeCacheSize = 33554432 {pd product}
bool ResizeOldPLAB = true {product}
bool ResizePLAB = true {product}
bool ResizeTLAB = true {pd product}
bool RestoreMXCSROnJNICalls = false {product}
bool RewriteBytecodes = false {pd product}
bool RewriteFrequentPairs = false {pd product}
intx SafepointPollOffset = 256 {C1 pd product}
intx SafepointSpinBeforeYield = 2000 {product}
bool SafepointTimeout = false {product}
intx SafepointTimeoutDelay = 10000 {product}
bool ScavengeBeforeFullGC = true {product}
intx SelfDestructTimer = 0 {product}
uintx SharedDummyBlockSize = 536870912 {product}
uintx SharedMiscCodeSize = 4194304 {product}
uintx SharedMiscDataSize = 4194304 {product}
uintx SharedReadOnlySize = 10485760 {product}
uintx SharedReadWriteSize = 12582912 {product}
bool ShowMessageBoxOnError = false {product}
intx SoftRefLRUPolicyMSPerMB = 1000 {product}
bool SplitIfBlocks = true {product}
intx StackRedPages = 1 {pd product}
intx StackShadowPages = 3 {pd product}
bool StackTraceInThrowable = true {product}
intx StackYellowPages = 2 {pd product}
bool StartAttachListener = false {product}
intx StarvationMonitorInterval = 200 {product}
bool StressLdcRewrite = false {product}
bool StressTieredRuntime = false {product}
bool SuppressFatalErrorMessage = false {product}
uintx SurvivorPadding = 3 {product}
intx SurvivorRatio = 8 {product}
intx SuspendRetryCount = 50 {product}
intx SuspendRetryDelay = 5 {product}
intx SyncFlags = 0 {product}
ccstr SyncKnobs = {product}
intx SyncVerbose = 0 {product}
uintx TLABAllocationWeight = 35 {product}
uintx TLABRefillWasteFraction = 64 {product}
uintx TLABSize = 0 {product}
bool TLABStats = true {product}
uintx TLABWasteIncrement = 4 {product}
uintx TLABWasteTargetPercent = 1 {product}
bool TaggedStackInterpreter = false {product}
intx TargetPLABWastePct = 10 {product}
intx TargetSurvivorRatio = 50 {product}
uintx TenuredGenerationSizeIncrement = 20 {product}
uintx TenuredGenerationSizeSupplement = 80 {product}
uintx TenuredGenerationSizeSupplementDecay = 2 {product}
intx ThreadPriorityPolicy = 0 {product}
bool ThreadPriorityVerbose = false {product}
uintx ThreadSafetyMargin = 52428800 {product}
intx ThreadStackSize = 0 {pd product}
uintx ThresholdTolerance = 10 {product}
intx Tier1BytecodeLimit = 10 {product}
bool Tier1OptimizeVirtualCallProfiling = true {C1 product}
bool Tier1ProfileBranches = true {C1 product}
bool Tier1ProfileCalls = true {C1 product}
bool Tier1ProfileCheckcasts = true {C1 product}
bool Tier1ProfileInlinedCalls = true {C1 product}
bool Tier1ProfileVirtualCalls = true {C1 product}
bool Tier1UpdateMethodData = false {product}
intx Tier2BackEdgeThreshold = 100000 {pd product}
intx Tier2CompileThreshold = 1500 {pd product}
intx Tier3BackEdgeThreshold = 100000 {pd product}
intx Tier3CompileThreshold = 2500 {pd product}
intx Tier4BackEdgeThreshold = 100000 {pd product}
intx Tier4CompileThreshold = 4500 {pd product}
bool TieredCompilation = false {pd product}
bool TimeLinearScan = false {C1 product}
bool TraceBiasedLocking = false {product}
bool TraceClassLoading = false {product rw}
bool TraceClassLoadingPreorder = false {product}
bool TraceClassResolution = false {product}
bool TraceClassUnloading = false {product rw}
bool TraceGen0Time = false {product}
bool TraceGen1Time = false {product}
ccstr TraceJVMTI = {product}
bool TraceLoaderConstraints = false {product rw}
bool TraceMonitorInflation = false {product}
bool TraceParallelOldGCTasks = false {product}
intx TraceRedefineClasses = 0 {product}
bool TraceSafepointCleanupTime = false {product}
bool TraceSuspendWaitFailures = false {product}
intx TypeProfileMajorReceiverPercent = 90 {product}
intx TypeProfileWidth = 2 {product}
intx UnguardOnExecutionViolation = 0 {product}
bool Use486InstrsOnly = false {product}
bool UseAdaptiveGCBoundary = false {product}
bool UseAdaptiveGenerationSizePolicyAtMajorCollection = true {p
bool UseAdaptiveGenerationSizePolicyAtMinorCollection = true {p
bool UseAdaptiveNUMAChunkSizing = true {product}
bool UseAdaptiveSizeDecayMajorGCCost = true {product}
bool UseAdaptiveSizePolicy = true {product}
bool UseAdaptiveSizePolicyFootprintGoal = true {product}
bool UseAdaptiveSizePolicyWithSystemGC = false {product}
bool UseAddressNop = false {product}
bool UseAltSigs = false {product}
bool UseAutoGCSelectPolicy = false {product}
bool UseBiasedLocking = true {product}
bool UseBoundThreads = true {product}
bool UseCMSBestFit = true {product}
bool UseCMSCollectionPassing = true {product}
bool UseCMSCompactAtFullCollection = true {product}
bool UseCMSInitiatingOccupancyOnly = false {product}
bool UseCodeCacheFlushing = false {product}
bool UseCompiler = true {product}
bool UseCompilerSafepoints = true {product}
bool UseConcMarkSweepGC = false {product}
bool UseCountLeadingZerosInstruction = false {product}
bool UseCounterDecay = true {product}
bool UseDepthFirstScavengeOrder = true {product}
bool UseFastAccessorMethods = true {product}
bool UseFastEmptyMethods = true {product}
bool UseFastJNIAccessors = true {product}
bool UseG1GC = false {product}
bool UseGCOverheadLimit = true {product}
bool UseGCTaskAffinity = false {product}
bool UseHeavyMonitors = false {product}
bool UseInlineCaches = true {product}
bool UseInterpreter = true {product}
bool UseLWPSynchronization = true {product}
bool UseLargePages = false {pd product}
bool UseLargePagesIndividualAllocation := false {pd product}
bool UseLoopCounter = true {product}
bool UseMaximumCompactionOnSystemGC = true {product}
bool UseMembar = false {product}
bool UseNUMA = false {product}
bool UseNewFeature1 = false {C1 product}
bool UseNewFeature2 = false {C1 product}
bool UseNewFeature3 = false {C1 product}
bool UseNewFeature4 = false {C1 product}
bool UseNewLongLShift = false {product}
bool UseNiagaraInstrs = false {product}
bool UseOSErrorReporting = false {pd product}
bool UseOnStackReplacement = true {pd product}
bool UsePSAdaptiveSurvivorSizePolicy = true {product}
bool UseParNewGC = false {product}
bool UseParallelDensePrefixUpdate = true {product}
bool UseParallelGC = false {product}
bool UseParallelOldGC = false {product}
bool UseParallelOldGCCompacting = true {product}
bool UseParallelOldGCDensePrefix = true {product}
bool UsePerfData = true {product}
bool UsePopCountInstruction = false {product}
intx UseSSE = 99 {product}
bool UseSSE42Intrinsics = false {product}
bool UseSerialGC = false {product}
bool UseSharedSpaces = true {product}
bool UseSignalChaining = true {product}
bool UseSpinning = false {product}
bool UseSplitVerifier = true {product}
bool UseStoreImmI16 = true {product}
bool UseStringCache = false {product}
bool UseTLAB = true {pd product}
bool UseThreadPriorities = true {pd product}
bool UseTypeProfile = true {product}
bool UseUTCFileTimestamp = true {product}
bool UseUnalignedLoadStores = false {product}
bool UseVMInterruptibleIO = true {product}
bool UseVectoredExceptions = false {pd product}
bool UseXMMForArrayCopy = false {product}
bool UseXmmI2D = false {product}
bool UseXmmI2F = false {product}
bool UseXmmLoadAndClearUpper = true {product}
bool UseXmmRegToRegMoveAll = false {product}
bool VMThreadHintNoPreempt = false {product}
intx VMThreadPriority = -1 {product}
intx VMThreadStackSize = 0 {pd product}
intx ValueMapInitialSize = 11 {C1 product}
intx ValueMapMaxLoopSize = 8 {C1 product}
bool VerifyMergedCPBytecodes = true {product}
intx WorkAroundNPTLTimedWaitHang = 1 {product}
uintx YoungGenerationSizeIncrement = 20 {product}
uintx YoungGenerationSizeSupplement = 80 {product}
uintx YoungGenerationSizeSupplementDecay = 8 {product}
uintx YoungPLABSize = 4096 {product}
bool ZeroTLAB = false {product}
intx hashCode = 0 {product}

以上這篇老生常談JVM的內(nèi)存溢出說明及參數(shù)調(diào)整就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解MyBatis延遲加載是如何實(shí)現(xiàn)的

    詳解MyBatis延遲加載是如何實(shí)現(xiàn)的

    MyBatis 的延遲加載(懶加載)特性允許在需要使用關(guān)聯(lián)對(duì)象數(shù)據(jù)時(shí)才進(jìn)行加載,而不是在執(zhí)行主查詢時(shí)就加載所有相關(guān)數(shù)據(jù),我們將通過以下幾個(gè)方面來深入了解MyBatis的延遲加載實(shí)現(xiàn)機(jī)制,需要的朋友可以參考下
    2024-07-07
  • java編程SpringSecurity入門原理及應(yīng)用簡介

    java編程SpringSecurity入門原理及應(yīng)用簡介

    Spring 是非常流行和成功的 Java 應(yīng)用開發(fā)框架,Spring Security 正是 Spring 家族中的成員。Spring Security 基于 Spring 框架,提供了一套 Web 應(yīng)用安全性的完整解決方案
    2021-09-09
  • Java字符轉(zhuǎn)碼之UTF-8互轉(zhuǎn)GBK具體實(shí)現(xiàn)

    Java字符轉(zhuǎn)碼之UTF-8互轉(zhuǎn)GBK具體實(shí)現(xiàn)

    在Java程序中字符串默認(rèn)的編碼方式是UTF-16編碼,因此需要將GBK編碼轉(zhuǎn)換為UTF-8編碼,主要是為了避免出現(xiàn)亂碼的情況,這篇文章主要給大家介紹了關(guān)于Java字符轉(zhuǎn)碼之UTF-8互轉(zhuǎn)GBK具體實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • SpringCloud之消息總線Spring Cloud Bus實(shí)例代碼

    SpringCloud之消息總線Spring Cloud Bus實(shí)例代碼

    這篇文章主要介紹了SpringCloud之消息總線Spring Cloud Bus實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • 如何將mybatis配置到springmvc中

    如何將mybatis配置到springmvc中

    為了更方便的連接數(shù)據(jù)庫,將mybatis配置到springMVC中。接下來通過本文給大家分享如何將mybatis配置到springmvc中,需要的朋友參考下吧
    2017-11-11
  • java可變參數(shù)當(dāng)做數(shù)組處理的方法示例

    java可變參數(shù)當(dāng)做數(shù)組處理的方法示例

    這篇文章主要介紹了java可變參數(shù)當(dāng)做數(shù)組處理的方法,結(jié)合實(shí)例形式分析了java可變參數(shù)當(dāng)做數(shù)組處理相關(guān)原理、步驟與操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Java對(duì)文本文件MD5加密并ftp傳送到遠(yuǎn)程主機(jī)目錄的實(shí)現(xiàn)方法

    Java對(duì)文本文件MD5加密并ftp傳送到遠(yuǎn)程主機(jī)目錄的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Java對(duì)文本文件MD5加密并ftp傳送到遠(yuǎn)程主機(jī)目錄的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • SpringBoot?Bean實(shí)例化流程解析

    SpringBoot?Bean實(shí)例化流程解析

    在SpringBoot啟動(dòng)過程中會(huì)執(zhí)行refreshContext()方法,而在其執(zhí)行過程中,又會(huì)調(diào)用finishBeanFactoryInitialization()方法,該方法負(fù)責(zé)了Bean的實(shí)例化,那么本文將從源碼跟讀的角度來解析一下具體流程
    2023-08-08
  • 淺析JDK和Tomcat的安裝與配置方法

    淺析JDK和Tomcat的安裝與配置方法

    這篇文章主要介紹了JDK和Tomcat的安裝與配置方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-12-12
  • Java程序執(zhí)行時(shí)間的2種簡單方法

    Java程序執(zhí)行時(shí)間的2種簡單方法

    這篇文章介紹了Java程序執(zhí)行時(shí)間的2種簡單方法,有需要的朋友可以參考一下
    2013-09-09

最新評(píng)論