




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、JVM內(nèi)存模型及垃圾收集策略解析(1)2010-02-22 08:58 狂放不羈 JavaEye 字號:T | T垃圾收集器策略從20世紀(jì)60年代就已經(jīng)流行起來了,相比于其他編程語言,Java語言是目前使用最多的依賴于垃圾收集器的語言。AD:WOT2015 互聯(lián)網(wǎng)運(yùn)維與開發(fā)者大會 熱銷搶票JVM內(nèi)存模型是Java的核心技術(shù)之一,之前51CTO曾為大家介紹過JVM分代垃圾回收策略的基礎(chǔ)概念,現(xiàn)在很多編程語言都引入了類似Java JVM的內(nèi)存模型和垃圾收集器的機(jī)制,下面我們將主要針對Java中的JVM內(nèi)存模型及垃圾收集的具體策略進(jìn)行綜合的分析。一 JVM內(nèi)存模型1.1
2、 Java棧Java棧是與每一個線程關(guān)聯(lián)的,JVM在創(chuàng)建每一個線程的時候,會分配一定的棧空間給線程。它主要用來存儲線程執(zhí)行過程中的局部變量,方法的返回值,以及方法調(diào)用上下文。??臻g隨著線程的終止而釋放。StackOverflowError:如果在線程執(zhí)行的過程中,??臻g不夠用,那么JVM就會拋出此異常,這種情況一般是死遞歸造成的。1.2 堆Java中堆是由所有的線程共享的一塊內(nèi)存區(qū)域,堆用來保存各種JAVA對象,比如數(shù)組,線程對象等。1.2.1 GenerationJVM堆一般又可以分為以下三部分: PermPerm代主要保存class,method,filed對象,這部門的空間一般不會溢出,
3、除非一次性加載了很多的類,不過在涉及到熱部署的應(yīng)用服務(wù)器的時候,有時候會遇到j(luò)ava.lang.OutOfMemoryError : PermGen space 的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署后,類的class沒有被卸載掉,這樣就造成了大量的class對象保存在了perm中,這種情況下,一般重新啟動應(yīng)用服務(wù)器可以解決問題。 TenuredTenured區(qū)主要保存生命周期長的對象,一般是一些老的對象,當(dāng)一些對象在Young復(fù)制轉(zhuǎn)移一定的次數(shù)以后,對象就會被轉(zhuǎn)移到Tenured區(qū),一般如果系統(tǒng)中用了application級別的緩存,緩存中的對象往往會被轉(zhuǎn)移到這
4、一區(qū)間。 YoungYoung區(qū)被劃分為三部分,Eden區(qū)和兩個大小嚴(yán)格相同的Survivor區(qū),其中Survivor區(qū)間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時復(fù)制對象用,在Young區(qū)間變滿的時候,minor GC就會將存活的對象移到空閑的Survivor區(qū)間中,根據(jù)JVM的策略,在經(jīng)過幾次垃圾收集后,任然存活于Survivor的對象將被移動到Tenured區(qū)間。1.2.2 Sizing the GenerationsJVM提供了相應(yīng)的參數(shù)來對內(nèi)存大小進(jìn)行配置。正如上面描述,JVM中堆被分為了3個大的區(qū)間,同時JVM也提供了一些選項(xiàng)對Young,Tenured的大小進(jìn)行控
5、制。 Total Heap-Xms :指定了JVM初始啟動以后初始化內(nèi)存-Xmx:指定JVM堆得最大內(nèi)存,在JVM啟動以后,會分配-Xmx參數(shù)指定大小的內(nèi)存給JVM,但是不一定全部使用,JVM會根據(jù)-Xms參數(shù)來調(diào)節(jié)真正用于JVM的內(nèi)存-Xmx -Xms之差就是三個Virtual空間的大小 Young Generation-XX:NewRatio=8意味著tenured 和 young的比值8:1,這樣eden+2*survivor=1/9堆內(nèi)存-XX:SurvivorRatio=32意味著eden和一個survivor的比值是32:1,這樣一個Survivor就占Young區(qū)的1/34.-X
6、mn 參數(shù)設(shè)置了年輕代的大小 Perm Generation-XX:PermSize=16M -XX:MaxPermSize=64MThread Stack-XX:Xss=128K1.3 堆棧分離的好處呵呵,其它的先不說了,就來說說面向?qū)ο蟮脑O(shè)計(jì)吧,當(dāng)然除了面向?qū)ο蟮脑O(shè)計(jì)帶來的維護(hù)性,復(fù)用性和擴(kuò)展性方面的好處外,我們看看面向?qū)ο笕绾吻擅畹睦昧硕褩7蛛x。如果從JAVA內(nèi)存模型的角度去理解面向?qū)ο蟮脑O(shè)計(jì),我們就會發(fā)現(xiàn)對象它完美的表示了堆和棧,對象的數(shù)據(jù)放在堆中,而我們編寫的那些方法一般都是運(yùn)行在棧中,因此面向?qū)ο蟮脑O(shè)計(jì)是一種非常完美的設(shè)計(jì)方式,它完美的統(tǒng)一了數(shù)據(jù)存儲和運(yùn)行。二 JAVA垃圾收集器
7、2.1 垃圾收集簡史垃圾收集提供了內(nèi)存管理的機(jī)制,使得應(yīng)用程序不需要在關(guān)注內(nèi)存如何釋放,內(nèi)存用完后,垃圾收集會進(jìn)行收集,這樣就減輕了因?yàn)槿藶榈墓芾韮?nèi)存而造成的錯誤,比如在C+語言里,出現(xiàn)內(nèi)存泄露時很常見的。Java語言是目前使用最多的依賴于垃圾收集器的語言,但是垃圾收集器策略從20世紀(jì)60年代就已經(jīng)流行起來了,比如Smalltalk,Eiffel等編程語言也集成了垃圾收集器的機(jī)制。2.2 常見的垃圾收集策略所有的垃圾收集算法都面臨同一個問題,那就是找出應(yīng)用程序不可到達(dá)的內(nèi)存塊,將其釋放,這里面得不可到達(dá)主要是指應(yīng)用程序已經(jīng)沒有內(nèi)存塊的引用了,而在JAVA中,某個對象對應(yīng)用程序是可到達(dá)的是指:這
8、個對象被根(根主要是指類的靜態(tài)變量,或者活躍在所有線程棧的對象的引用)引用或者對象被另一個可到達(dá)的對象引用。2.2.1 Reference Counting(引用計(jì)數(shù)) 引用計(jì)數(shù)是最簡單直接的一種方式,這種方式在每一個對象中增加一個引用的計(jì)數(shù),這個計(jì)數(shù)代表當(dāng)前程序有多少個引用引用了此對象,如果此對象的引用計(jì)數(shù)變?yōu)?,那么此對象就可以作為垃圾收集器的目標(biāo)對象來收集。優(yōu)點(diǎn):簡單,直接,不需要暫停整個應(yīng)用缺點(diǎn):1.需要編譯器的配合,編譯器要生成特殊的指令來進(jìn)行引用計(jì)數(shù)的操作,比如每次將對象賦值給新的引用,或者者對象的引用超出了作用域等。2.不能處理循環(huán)引用的問題2.2.2 跟蹤收集器跟蹤收
9、集器首先要暫停整個應(yīng)用程序,然后開始從根對象掃描整個堆,判斷掃描的對象是否有對象引用,這里面有三個問題需要搞清楚:1如果每次掃描整個堆,那么勢必讓GC的時間變長,從而影響了應(yīng)用本身的執(zhí)行。因此在JVM里面采用了分代收集,在新生代收集的時候minor gc只需要掃描新生代,而不需要掃描老生代。2JVM采用了分代收集以后,minor gc只掃描新生代,但是minor gc怎么判斷是否有老生代的對象引用了新生代的對象,JVM采用了卡片標(biāo)記的策略,卡片標(biāo)記將老生代分成了一塊一塊的,劃分以后的每一個塊就叫做一個卡片,JVM采用卡表維護(hù)了每一個塊的狀態(tài),當(dāng)JAVA程序運(yùn)行的時候,如果發(fā)現(xiàn)老生代對象引用或者
10、釋放了新生代對象的引用,那么就JVM就將卡表的狀態(tài)設(shè)置為臟狀態(tài),這樣每次minor gc的時候就會只掃描被標(biāo)記為臟狀態(tài)的卡片,而不需要掃描整個堆。具體如下圖:3GC在收集一個對象的時候會判斷是否有引用指向?qū)ο螅贘AVA中的引用主要有四種:Strong reference,Soft reference,Weak reference,Phantom reference. Strong Reference強(qiáng)引用是JAVA中默認(rèn)采用的一種方式,我們平時創(chuàng)建的引用都屬于強(qiáng)引用。如果一個對象沒有強(qiáng)引用,那么對象就會被回收。1. public void testStrongRefere
11、nce() 2. Object referent = new Object(); 3. Object strongReference = referent; 4. referent = null; 5. System.gc(); 6. assertNotNull(strongReference); 7. Soft Reference軟引用的對象在GC的時候不會被回收,只有當(dāng)內(nèi)存不夠用的時候才會真正的回收,因此軟引用適合緩
12、存的場合,這樣使得緩存中的對象可以盡量的再內(nèi)存中待長久一點(diǎn)。1. Public void testSoftReference() 2. String str = "test" 3. SoftReference<String> softreference = new SoftReference<String>(str); 4. str=null; 5. System.gc(); 6
13、. assertNotNull(softreference.get(); 7. Weak reference弱引用有利于對象更快的被回收,假如一個對象沒有強(qiáng)引用只有弱引用,那么在GC后,這個對象肯定會被回收。1. Public void testWeakReference() 2. String str = "test" 3. WeakReference<String> weakReference = new&
14、#160;WeakReference<String>(str); 4. str=null; 5. System.gc(); 6. assertNull(weakReference.get(); 7. Phantom reference Mark-Sweep Collector(標(biāo)記-清除收集器)標(biāo)記清除收集器最早由Lisp的發(fā)明人于1960年提出,標(biāo)記清除收集器停止所有的工作,從根掃描每個活躍的對象,然后標(biāo)記掃描過的對象,標(biāo)記完成以后,清除那些沒有被標(biāo)記的對象。優(yōu)點(diǎn):1 解決循環(huán)引用的問題2 不需要編譯器的
15、配合,從而就不執(zhí)行額外的指令缺點(diǎn):1每個活躍的對象都要進(jìn)行掃描,收集暫停的時間比較長。 Copying Collector(復(fù)制收集器)復(fù)制收集器將內(nèi)存分為兩塊一樣大小空間,某一個時刻,只有一個空間處于活躍的狀態(tài),當(dāng)活躍的空間滿的時候,GC就會將活躍的對象復(fù)制到未使用的空間中去,原來不活躍的空間就變?yōu)榱嘶钴S的空間。復(fù)制收集器具體過程可以參考下圖:優(yōu)點(diǎn):1 只掃描可以到達(dá)的對象,不需要掃描所有的對象,從而減少了應(yīng)用暫停的時間缺點(diǎn):1需要額外的空間消耗,某一個時刻,總是有一塊內(nèi)存處于未使用狀態(tài)2復(fù)制對象需要一定的開銷 Mark-Compact Collector(標(biāo)記-
16、整理收集器)標(biāo)記整理收集器汲取了標(biāo)記清除和復(fù)制收集器的優(yōu)點(diǎn),它分兩個階段執(zhí)行,在第一個階段,首先掃描所有活躍的對象,并標(biāo)記所有活躍的對象,第二個階段首先清除未標(biāo)記的對象,然后將活躍的的對象復(fù)制到堆得底部。標(biāo)記整理收集器的過程示意圖請參考下圖:Mark-compact策略極大的減少了內(nèi)存碎片,并且不需要像Copy Collector一樣需要兩倍的空間。2.3 JVM的垃圾收集策略 GC的執(zhí)行時要耗費(fèi)一定的CPU資源和時間的,因此在JDK1.2以后,JVM引入了分代收集的策略,其中對新生代采用"Mark-Compact"策略,而對老生代采用了“Mark-Sweep&q
17、uot;的策略。其中新生代的垃圾收集器命名為“minor gc”,老生代的GC命名為"Full Gc 或者M(jìn)ajor GC".其中用System.gc()強(qiáng)制執(zhí)行的是Full Gc.2.3.1 Serial CollectorSerial Collector是指任何時刻都只有一個線程進(jìn)行垃圾收集,這種策略有一個名字“stop the whole world",它需要停止整個應(yīng)用的執(zhí)行。這種類型的收集器適合于單CPU的機(jī)器。Serial Copying Collector此種GC用-XX:UseSerialGC選項(xiàng)配置,它只用于新生代對象的收集。1.5.0以后。-X
18、X:MaxTenuringThreshold來設(shè)置對象復(fù)制的次數(shù)。當(dāng)eden空間不夠的時候,GC會將eden的活躍對象和一個名叫From survivor空間中尚不夠資格放入Old代的對象復(fù)制到另外一個名字叫To Survivor的空間。而此參數(shù)就是用來說明到底From survivor中的哪些對象不夠資格,假如這個參數(shù)設(shè)置為31,那么也就是說只有對象復(fù)制31次以后才算是有資格的對象。這里需要注意幾個個問題: From Survivor和To survivor的角色是不斷的變化的,同一時間只有一塊空間處于使用狀態(tài),這個空間就叫做From Survivor區(qū),當(dāng)復(fù)制一次后角色就發(fā)生了
19、變化。 如果復(fù)制的過程中發(fā)現(xiàn)To survivor空間已經(jīng)滿了,那么就直接復(fù)制到old generation. 比較大的對象也會直接復(fù)制到Old generation,在開發(fā)中,我們應(yīng)該盡量避免這種情況的發(fā)生。Serial Mark-Compact Collector串行的標(biāo)記-整理收集器是JDK5 update6之前默認(rèn)的老生代的垃圾收集器,此收集使得內(nèi)存碎片最少化,但是它需要暫停的時間比較長。2.3.2 Parallel Collector Parallel Collector主要是為了應(yīng)對多CPU,大數(shù)據(jù)量的環(huán)境。Parallel Colle
20、ctor又可以分為以下兩種:Parallel Copying Collector此種GC用-XX:UseParNewGC參數(shù)配置,它主要用于新生代的收集,此GC可以配合CMS一起使用。1.4.1以后Parallel Mark-Compact Collector,此種GC用-XX:UseParallelOldGC參數(shù)配置,此GC主要用于老生代對象的收集。1.6.0Parallel scavenging Collector此種GC用-XX:UseParallelGC參數(shù)配置,它是對新生代對象的垃圾收集器,但是它不能和CMS配合使用,它適合于比較大新生代的情況,此收集器起始于jdk 1.4.0。它比
21、較適合于對吞吐量高于暫停時間的場合,Serial gc和Parallel gc可以用如下的圖來表示:2.3.3 Concurrent CollectorConcurrent Collector通過并行的方式進(jìn)行垃圾收集,這樣就減少了垃圾收集器收集一次的時間,這種GC在實(shí)時性要求高于吞吐量的時候比較有用。此種GC可以用參數(shù)-XX:UseConcMarkSweepGC配置,此GC主要用于老生代和Perm代的收集?!揪庉嬐扑]】1. Java的未來:百家爭鳴的JVM2. 有關(guān)JVM處理Java數(shù)組方法的思考3. JVM分代垃圾回收策略的基礎(chǔ)概念4. JVM概念之Java對象的大小與引用類型5. JVM
22、基礎(chǔ)概念總結(jié):數(shù)據(jù)類型、堆與棧this.memoryLimit = (long)(jobConf.getLong(MRJobConfig.REDUCE_MEMORY_TOTAL_BYTES, Math.min(Runtime.getRuntime().maxMemory(), Integer.MAX_VALUE) * maxInMemCopyUse);maxMemory()這個方法返回的是java虛擬機(jī)(這個進(jìn)程)能構(gòu)從操作系統(tǒng)那里挖到的最大的內(nèi)存,以字節(jié)為單位.totalMemory()這個方法返回的是java虛擬機(jī)現(xiàn)在已經(jīng)從操作系統(tǒng)那里挖過來的內(nèi)存大小,也就是java虛擬機(jī)這個進(jìn)程當(dāng)時所占
23、用的所有內(nèi)存。freeMemory為當(dāng)前jvm中沒有使用的內(nèi)存。JVM基礎(chǔ):JVM參數(shù)設(shè)置、分析央邦0首付,低押金先就業(yè)后付款上海央邦學(xué)一送一,超值!50000年薪起,頂級4G手機(jī)開發(fā)!【安博亞威】CCIE考試通過率第一!大數(shù)據(jù)與互聯(lián)網(wǎng)技術(shù)峰會免費(fèi)注冊java培訓(xùn)到達(dá)內(nèi),行業(yè)領(lǐng)先品牌中國IT實(shí)驗(yàn)室收集整理 佚名 2012-2-25 9:18:41 保存本文 推薦給好友 收藏本頁歡迎進(jìn)入Java社區(qū)論壇,與200萬技術(shù)人員互動交流 >>進(jìn)入?yún)?shù)名稱含義默認(rèn)值 -Xms初始堆大小物理內(nèi)存的1/64(<1GB)默認(rèn)(Min
24、HeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存小于40%時,JVM就會增大堆直到-Xmx的最大限制.-Xmx最大堆大小物理內(nèi)存的1/4(<1GB)默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時,JVM會減少堆直到 -Xms的最小限制-Xmn年輕代大小(1.4or lator) 注意:此處的大小是(eden+ 2 survivor space).與jmap -heap中顯示的New gen是不同的。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小.增大年輕代后,將會減小年老代大小.此值對系統(tǒng)性能影響較大,Sun官方推薦配置為整個堆
25、的3/8-XX:NewSize設(shè)置年輕代大小(for 1.3/1.4) -XX:MaxNewSize年輕代最大值(for 1.3/1.4) -XX:PermSize設(shè)置持久代(perm gen)初始值物理內(nèi)存的1/64 -XX:MaxPermSize設(shè)置持久代最大值物理內(nèi)存的1/4 -Xss每個線程的堆棧大小 JDK5.0以后每個線程堆棧大小為1M,以前每個線程堆棧大小為256K.更具應(yīng)用的線程所需內(nèi)存大小進(jìn)行 調(diào)整.在相同物理內(nèi)存下,減小這個值能生成更多的線程.但是操作系統(tǒng)對一個進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成
26、,經(jīng)驗(yàn)值在30005000左右一般小的應(yīng)用, 如果棧不是很深, 應(yīng)該是128k夠用的 大的應(yīng)用建議使用256k。這個選項(xiàng)對性能影響比較大,需要嚴(yán)格的測試。(校長)和threadstacksize選項(xiàng)解釋很類似,官方文檔似乎沒有解釋,在論壇中有這樣一句話:"”-Xss is translated in a VM flag named ThreadStackSize”一般設(shè)置這個值就可以了。-XX:ThreadStackSizeThread Stack Size (0 means use default stack size) Sparc: 512; Solaris x86:
27、320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.-XX:NewRatio年輕代(包括Eden和兩個Survivor區(qū))與年老代的比值(除去持久代) -XX:NewRatio=4表示年輕代與年老代所占比值為1:4,年輕代占整個堆棧的1/5Xms=Xmx并且設(shè)置了Xmn的情況下,該參數(shù)不需要進(jìn)行設(shè)置。-XX:SurvivorRatioEden區(qū)與Survivor區(qū)的大小比值 設(shè)置為8,則兩個
28、Survivor區(qū)與一個Eden區(qū)的比值為2:8,一個Survivor區(qū)占整個年輕代的1/10-XX:LargePageSizeInBytes內(nèi)存頁的大小不可設(shè)置過大, 會影響Perm的大小 =128m-XX:+UseFastAccessorMethods原始類型的快速優(yōu)化 -XX:+DisableExplicitGC關(guān)閉System.gc() 這個參數(shù)需要嚴(yán)格的測試-XX:MaxTenuringThreshold垃圾最大年齡 如果設(shè)置為0的話,則年輕代對象不經(jīng)過Survivor區(qū),直接進(jìn)入年老代. 對于年老代比較多的應(yīng)用,可以提高效率.如果
29、將此值設(shè)置為一個較大值,則年輕代對象會在Survivor區(qū)進(jìn)行多次復(fù)制,這樣可以增加對象再年輕代的存活 時間,增加在年輕代即被回收的概率該參數(shù)只有在串行GC時才有效.-XX:+AggressiveOpts加快編譯 -XX:+UseBiasedLocking鎖機(jī)制的性能改善 -Xnoclassgc禁用垃圾回收 -XX:SoftRefLRUPolicyMSPerMB每兆堆空閑空間中SoftReference的存活時間1ssoftly reachable objects will remain alive for some amoun
30、t of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap-XX:PretenureSizeThreshold對象超過多大是直接在舊生代分配0單位字節(jié) 新生代采用Parallel Scavenge GC時無效另一種直接在舊生代分配的情況是大的數(shù)組對象,且數(shù)組中無外部引用對象.-XX:TLABWasteTargetPercentTLAB占eden區(qū)的百分比1% -XX:+CollectGen0Fi
31、rstFullGC時是否先YGCfalse 并行收集器相關(guān)參數(shù)-XX:+UseParallelGCFull GC采用parallel MSC(此項(xiàng)待驗(yàn)證) 選擇垃圾收集器為并行收集器.此配置僅對年輕代有效.即上述配置下,年輕代使用并發(fā)收集,而年老代仍舊使用串行收集.(此項(xiàng)待驗(yàn)證)-XX:+UseParNewGC設(shè)置年輕代為并行收集 可與CMS收集同時使用JDK5.0以上,JVM會根據(jù)系統(tǒng)配置自行設(shè)置,所以無需再設(shè)置此值-XX:ParallelGCThreads并行收集器的線程數(shù) 此值最好配置與處理器數(shù)目相等 同樣適用于CMS-XX:+UseParalle
32、lOldGC年老代垃圾收集方式為并行收集(Parallel Compacting) 這個是JAVA 6出現(xiàn)的參數(shù)選項(xiàng)-XX:MaxGCPauseMillis每次年輕代垃圾回收的最長時間(最大暫停時間) 如果無法滿足此時間,JVM會自動調(diào)整年輕代大小,以滿足此值.-XX:+UseAdaptiveSizePolicy自動選擇年輕代區(qū)大小和相應(yīng)的Survivor區(qū)比例 設(shè)置此選項(xiàng)后,并行收集器會自動選擇年輕代區(qū)大小和相應(yīng)的Survivor區(qū)比例,以達(dá)到目標(biāo)系統(tǒng)規(guī)定的最低相應(yīng)時間或者收集頻率等,此值建議使用并行收集器時,一直打開.-XX:GCTimeRatio設(shè)置垃圾回收
33、時間占程序運(yùn)行時間的百分比 公式為1/(1+n)-XX:+ScavengeBeforeFullGCFull GC前調(diào)用YGCtrueDo young generation GC prior to a full GC. (Introduced in 1.4.1.)CMS相關(guān)參數(shù)-XX:+UseConcMarkSweepGC使用CMS內(nèi)存收集 測試中配置這個以后,-XX:NewRatio=4的配置失效了,原因不明.所以,此時年輕代大小最好用-Xmn設(shè)置.?-XX:+AggressiveHeap 試圖是使用大量的物理內(nèi)存長時間大內(nèi)存使用的優(yōu)化,能檢查計(jì)算資源
34、(內(nèi)存, 處理器數(shù)量)至少需要256MB內(nèi)存大量的CPU內(nèi)存, (在1.4.1在4CPU的機(jī)器上已經(jīng)顯示有提升)-XX:CMSFullGCsBeforeCompaction多少次后進(jìn)行內(nèi)存壓縮 由于并發(fā)收集器不對內(nèi)存空間進(jìn)行壓縮,整理,所以運(yùn)行一段時間以后會產(chǎn)生"碎片",使得運(yùn)行效率降低.此值設(shè)置運(yùn)行多少次GC以后對內(nèi)存空間進(jìn)行壓縮,整理.-XX:+CMSParallelRemarkEnabled降低標(biāo)記停頓 -XX+UseCMSCompactAtFullCollection在FULL GC的時候, 對年老代的壓縮 CMS是不會移動
35、內(nèi)存的, 因此, 這個非常容易產(chǎn)生碎片, 導(dǎo)致內(nèi)存不夠用, 因此, 內(nèi)存的壓縮這個時候就會被啟用。 增加這個參數(shù)是個好習(xí)慣??赡軙绊懶阅?但是可以消除碎片-XX:+UseCMSInitiatingOccupancyOnly使用手動定義初始化定義開始CMS收集 禁止hostspot自行觸發(fā)CMS GC-XX:CMSInitiatingOccupancyFraction=70使用cms作為垃圾回收使用70后開始CMS收集92為了保證不出現(xiàn)promotion failed(見下面介紹)錯誤,該值的設(shè)置需要滿足以下公式CMSInitiatingOccupancyFraction計(jì)算公式-X
36、X:CMSInitiatingPermOccupancyFraction設(shè)置Perm Gen使用到達(dá)多少比率時觸發(fā)92 -XX:+CMSIncrementalMode設(shè)置為增量模式 用于單CPU情況-XX:+CMSClassUnloadingEnabled 輔助信息-XX:+PrintGC 輸出形式:GC 118250K->113543K(130112K), 0.0094143 secsFull GC 121376K->10414K(130112K), 0.0650971 secs-XX:+PrintGCD
37、etails 輸出形式:GC DefNew: 8614K->781K(9088K), 0.0123035 secs 118250K->113543K(130112K), 0.0124633 secsGC DefNew: 8614K->8614K(9088K), 0.0000665 secsTenured: 112761K->10414K(121024K), 0.0433488 secs 121376K->10414K(130112K), 0.0436268 secs-XX:+PrintGCTimeStamps
38、;-XX:+PrintGC:PrintGCTimeStamps 可與-XX:+PrintGC -XX:+PrintGCDetails混合使用輸出形式:11.851: GC 98328K->93620K(130112K), 0.0082960 secs-XX:+PrintGCApplicationStoppedTime打印垃圾回收期間程序暫停的時間.可與上面混合使用 輸出形式:Total time for which application threads were stopped: 0.0468229 seconds-XX:+PrintGCApplicat
39、ionConcurrentTime打印每次垃圾回收前,程序未中斷的執(zhí)行時間.可與上面混合使用 輸出形式:Application time: 0.5291524 seconds-XX:+PrintHeapAtGC打印GC前后的詳細(xì)堆棧信息 -Xloggc:filename把相關(guān)日志信息記錄到文件以便分析.與上面幾個配合使用 -XX:+PrintClassHistogramgarbage collects before printing the histogram. -XX:+PrintTLAB查看TLAB空間的使用情況&
40、#160; XX:+PrintTenuringDistribution查看每次minor GC后新的存活周期的閾值 Desired survivor size 1048576 bytes, new threshold 7 (max 15)new threshold 7即標(biāo)識新的存活周期的閾值為7。GC性能方面的考慮 對于GC的性能主要有2個方面的指標(biāo):吞吐量throughput(工作時間不算gc的時間占總的時間比)和暫停pause(gc發(fā)生時app對外顯示的無法響應(yīng))。 1. Total Heap
41、60; 默認(rèn)情況下,vm會增加/減少heap大小以維持free space在整個vm中占的比例,這個比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。 一般而言,server端的app會有以下規(guī)則: 對vm分配盡可能多的memory; 將Xms和Xmx設(shè)為一樣的值。如果虛擬機(jī)啟動時設(shè)置使用的內(nèi)存比較小,這個時候又需要初始化很多對象,虛擬機(jī)就必須重復(fù)地增加內(nèi)存。 處理器核數(shù)增加,內(nèi)存也跟著
42、增大。 2. The Young Generation 另外一個對于app流暢性運(yùn)行影響的因素是young generation的大小。young generation越大,minor collection越少;但是在固定heap size情況下,更大的young generation就意味著小的tenured generation,就意味著更多的major collection(major collection會引發(fā)minor collection)。 NewRatio反映的是youn
43、g和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,將這兩個值設(shè)為一樣就固定了young generation的大小(同Xms和Xmx設(shè)為一樣)。 如果希望,SurvivorRatio也可以優(yōu)化survivor的大小,不過這對于性能的影響不是很大。SurvivorRatio是eden和survior大小比例。 一般而言,server端的app會有以下規(guī)則: 首先決定能分配給vm的最大的heap
44、size,然后設(shè)定最佳的young generation的大小; 如果heap size固定后,增加young generation的大小意味著減小tenured generation大小。讓tenured generation在任何時候夠大,能夠容納所有l(wèi)ive的data(留10%-20%的空余)。 經(jīng)驗(yàn)&&規(guī)則 年輕代大小選擇 ?響應(yīng)時間優(yōu)先的應(yīng)用:盡可能設(shè)大,直到接近系統(tǒng)的最低響應(yīng)時間限制(根據(jù)實(shí)際情況選擇)。在此種情況下,年輕代收集發(fā)生的頻率也是最小的。同時,減少
45、到達(dá)年老代的對象。 吞吐量優(yōu)先的應(yīng)用:盡可能的設(shè)置大,可能到達(dá)Gbit的程度。因?yàn)閷憫?yīng)時間沒有要求,垃圾收集可以并行進(jìn)行,一般適合8CPU以上的應(yīng)用。 避免設(shè)置過小。當(dāng)新生代設(shè)置過小時會導(dǎo)致:1.YGC次數(shù)更加頻繁 2.可能導(dǎo)致YGC對象直接進(jìn)入舊生代,如果此時舊生代滿了,會觸發(fā)FGC. 年老代大小選擇 ?響應(yīng)時間優(yōu)先的應(yīng)用:年老代使用并發(fā)收集器,所以其大小需要小心設(shè)置,一般要考慮并發(fā)會話率和會話持續(xù)時間等一些參數(shù)。如果堆設(shè)置小了,可以會造成內(nèi)存碎 片,高回收頻率以及應(yīng)用暫停而使用傳統(tǒng)
46、的標(biāo)記清除方式;如果堆大了,則需要較長的收集時間。最優(yōu)化的方案,一般需要參考以下數(shù)據(jù)獲得: 并發(fā)垃圾收集信息、持久代并發(fā)收集次數(shù)、傳統(tǒng)GC信息、花在年輕代和年老代回收上的時間比例。 吞吐量優(yōu)先的應(yīng)用:一般吞吐量優(yōu)先的應(yīng)用都有一個很大的年輕代和一個較小的年老代。原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活對象。 較小堆引起的碎片問題 因?yàn)槟昀洗牟l(fā)收集器使用標(biāo)記,清除算法,所以不會對堆進(jìn)行壓縮。當(dāng)收集器回收時,他會
47、把相鄰的空間進(jìn)行合并,這樣可以分配給較大的對象。但是,當(dāng)堆空間較小時,運(yùn)行一段時間以后,就會出現(xiàn)"碎片",如果并發(fā)收集器找不到足夠的空間,那么并發(fā)收集器將會停止,然后使用傳統(tǒng)的標(biāo)記,清除方式進(jìn)行回收。如果出現(xiàn)"碎片",可能需要進(jìn)行如下配置: -XX:+UseCMSCompactAtFullCollection:使用并發(fā)收集器時,開啟對年老代的壓縮。 -XX:CMSFullGCsBeforeCompaction=0:上面配置開啟的情況下,這里設(shè)置多少次Full GC后,對年老代進(jìn)行壓縮
48、 用64位操作系統(tǒng),Linux下64位的jdk比32位jdk要慢一些,但是吃得內(nèi)存更多,吞吐量更大 XMX和XMS設(shè)置一樣大,MaxPermSize和MinPermSize設(shè)置一樣大,這樣可以減輕伸縮堆大小帶來的壓力 使用CMS的好處是用盡量少的新生代,經(jīng)驗(yàn)值是128M256M, 然后老生代利用CMS并行收集, 這樣能保證系統(tǒng)低延遲的吞吐效率。 實(shí)際上cms的收集停頓時間非常的短,2G的內(nèi)存, 大約2080ms的應(yīng)用程序停頓時間 系統(tǒng)停頓的時候可能是G
49、C的問題也可能是程序的問題,多用jmap和jstack查看,或者killall -3 java,然后查看java控制臺日志,能看出很多問題。(相關(guān)工具的使用方法將在后面的blog中介紹) 仔細(xì)了解自己的應(yīng)用,如果用了緩存,那么年老代應(yīng)該大一些,緩存的HashMap不應(yīng)該無限制長,建議采用LRU算法的Map做緩存,LRUMap的最大長度也要根據(jù)實(shí)際情況設(shè)定。 采用并發(fā)回收時,年輕代小一點(diǎn),年老代要大,因?yàn)槟昀洗笥玫氖遣l(fā)回收,即使時間長點(diǎn)也不會影響其他程序繼續(xù)運(yùn)行,網(wǎng)站不會停頓 JVM參數(shù)
50、的設(shè)置(特別是 Xmx Xms Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等參數(shù)的設(shè)置沒有一個固定的公式,需要根據(jù)PV old區(qū)實(shí)際數(shù)據(jù) YGC次數(shù)等多方面來衡量。為了避免promotion faild可能會導(dǎo)致xmn設(shè)置偏小,也意味著YGC的次數(shù)會增多,處理并發(fā)訪問的能力下降等問題。每個參數(shù)的調(diào)整都需要經(jīng)過詳細(xì)的性能測試,才能找到特定應(yīng)用的最佳配置。 promotion failed: 垃圾回收時promotion failed是個很頭痛的問題,一般可能是兩種原因產(chǎn)生,第
51、一個原因是救助空間不夠,救助空間里的對象還不應(yīng)該被移動到年老代,但年輕代又有很多對象需要放入救助空間;第二個原因是年老代沒有足夠的空間接納來自年輕代的對象;這兩種情況都會轉(zhuǎn)向Full GC,網(wǎng)站停頓時間較長。 解決方方案一: 第一個原因我的最終解決辦法是去掉救助空間,設(shè)置-XX:SurvivorRatio=65536 -XX:MaxTenuringThreshold=0即可,第二個原因我的解決辦法是設(shè)置CMSInitiatingOccupancyFraction為某個值(假設(shè)70),這樣年老代空間到70%時就開始執(zhí)行CMS
52、,年老代有足夠的空間接納來自年輕代的對象。 解決方案一的改進(jìn)方案: 又有改進(jìn)了,上面方法不太好,因?yàn)闆]有用到救助空間,所以年老代容易滿,CMS執(zhí)行會比較頻繁。我改善了一下,還是用救助空間,但是把救助空間加大,這樣也不會有promotion failed。具體操作上,32位Linux和64位Linux好像不一樣,64位系統(tǒng)似乎只要配置MaxTenuringThreshold參數(shù),CMS還是有暫停。為了解決暫停問題和promotion failed問題,最后我設(shè)置-XX:SurvivorRatio=1 ,并把MaxTenuringThreshold去掉,這樣即沒有暫停又不會有promotoin failed,而且更重要的是,年老代和永久代上升非常慢(因?yàn)楹枚鄬ο蟮讲涣四昀洗捅换厥樟耍訡MS執(zhí)行頻率非常低,好幾個小時才執(zhí)行一次,這樣,服務(wù)器都不
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025屆河南省周口市扶溝高級中學(xué)高三二輪檢測試題(二模)語文試題試卷含解析
- 2024-2025學(xué)年湖南省茶陵三中新高考物理試題適應(yīng)性訓(xùn)練(二)含解析
- 酒泉職業(yè)技術(shù)學(xué)院《數(shù)學(xué)解題方法》2023-2024學(xué)年第一學(xué)期期末試卷
- 鶴壁汽車工程職業(yè)學(xué)院《第二外語德語》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖南工學(xué)院《程序設(shè)計(jì)基礎(chǔ)理論》2023-2024學(xué)年第二學(xué)期期末試卷
- 畢節(jié)工業(yè)職業(yè)技術(shù)學(xué)院《裝飾設(shè)計(jì)基礎(chǔ)》2023-2024學(xué)年第二學(xué)期期末試卷
- 揚(yáng)州大學(xué)《現(xiàn)代分析》2023-2024學(xué)年第二學(xué)期期末試卷
- 古人對時間的總結(jié)
- 公司投資的基本理念及方法論
- 公共交通車輛性能檢測制度
- 電網(wǎng)工程設(shè)備材料信息參考價(2024年第四季度)
- 20以內(nèi)退位減法口算練習(xí)題100題30套(共3000題)
- GB/T 13668-2015鋼制書柜、資料柜通用技術(shù)條件
- 易制毒化學(xué)品安全教育培訓(xùn)《教育培訓(xùn)記錄表》
- 精神病學(xué)簡答題
- 2023年鄂爾多斯生態(tài)環(huán)境職業(yè)學(xué)院單招考試面試題庫及答案解析
- Q∕SY 01004-2016 氣田水回注技術(shù)規(guī)范
- 氣管支氣管結(jié)核診斷和治療指南
- 高中臨界生沖刺一本培養(yǎng)方案
- 供應(yīng)商社會準(zhǔn)則符合性自審問卷
- 城鎮(zhèn)燃?xì)饧映艏夹g(shù)規(guī)程CJJ T148
評論
0/150
提交評論