国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
JVM內(nèi)存模型以及垃圾收集策略解析【續(xù)】 - 信心,恒心,野心,愛心兼具者,可謂準(zhǔn)成功人士...

JVM內(nèi)存模型以及垃圾收集策略解析【續(xù)】

文章分類:Java編程

今天接著補(bǔ)全上篇博文。

三 垃圾收集策略配置

3.1 吞吐量優(yōu)先

吞吐量是指GC的時(shí)間與運(yùn)行總時(shí)間的比值,比如系統(tǒng)運(yùn)行了100分鐘,而GC占用了一分鐘,那么吞吐量就是99%,吞吐量優(yōu)先一般運(yùn)用于對響應(yīng)性要求不高的場合,比如web應(yīng)用,因?yàn)榫W(wǎng)絡(luò)傳輸本來就有延遲的問題,GC造成的短暫的暫停使得用戶以為是網(wǎng)絡(luò)阻塞所致。

吞吐量優(yōu)先可以通過-XX:GCTimeRatio來指定。

當(dāng)通過-XX:GCTimeRatio不能滿足系統(tǒng)的要求以后,我們可以更加細(xì)致的來對JVM進(jìn)行調(diào)優(yōu)。

首先因?yàn)橐蟾咄掏铝?,這樣就需要一個(gè)較大的Young generation,此時(shí)就需要引入“Parallel scavenging Collector”,可以通過參數(shù):-XX:UseParallelGC來配置。

 java -server -Xms3072m -Xmx3072m -XX:NewSize=2560m -XX:MaxNewSize=2560 XX:SurvivorRatio=2 -XX:+UseParallelGC 

當(dāng)年輕代使用了"Parallel scavenge collector"后,老生代就不能使用"CMS"GC了,在JDK1.6之前,此時(shí)老生代只能采用串行收集,而JDK1.6引入了并行版本的老生代收集器,可以用參數(shù)-XX:UseParallelOldGC來配置。

3.1.1 控制并行的線程數(shù)

缺省情況下,Parallel scavenging Collector 會開啟與cpu數(shù)量相同的線程進(jìn)行并行的收集,但是也可以調(diào)節(jié)并行的線程數(shù)。假如你想用4個(gè)并行的線程去收集Young generation的話,那么就可以配置-XX:ParallelGCThreads=4,此時(shí)JVM的配置參數(shù)如下:

 java -server -Xms3072m -Xmx3072m -XX:NewSize=2560m -XX:MaxNewSize=2560 XX:SurvivorRatio=2 -XX:+UseParallelGC -XX:ParallelGCThreads=4

3.1.2 自動(dòng)調(diào)節(jié)新生代

在采用了"Parallel scavenge collector"后,此GC會根據(jù)運(yùn)行時(shí)的情況自動(dòng)調(diào)節(jié)survivor ratio來使得性能最優(yōu),因此"Parallel scavenge collector"應(yīng)該總是開啟此參數(shù)。

此時(shí)JVM的參數(shù)配置如下:

java -server -Xms3072m -Xmx3072m -XX:+UseParallelGC    -XX:ParallelGCThreads=4 -XX:+UseAdaptiveSizePolicy

 

3.2 響應(yīng)時(shí)間優(yōu)先

響應(yīng)時(shí)間優(yōu)先是指GC每次運(yùn)行的時(shí)間不能太久,這種情況一般使用與對及時(shí)性要求很高的系統(tǒng),比如股票系統(tǒng)等。

響應(yīng)時(shí)間優(yōu)先可以通過參數(shù)-XX:MaxGCPauseMillis來配置,配置以后JVM將會自動(dòng)調(diào)節(jié)年輕代,老生代的內(nèi)存分配來滿足參數(shù)設(shè)置。

在一般情況下,JVM的默認(rèn)配置就可以滿足要求,只有默認(rèn)配置不能滿足系統(tǒng)的要求時(shí)候,才會根據(jù)具體的情況來對JVM進(jìn)行性能調(diào)優(yōu)。如果采用默認(rèn)的配置不能滿足系統(tǒng)的要求,那么此時(shí)就可以自己動(dòng)手來調(diào)節(jié)。

此時(shí)"Young generation"可以采用"Parallel copying collector",而"Old generation"則可以采用"Concurrent Collector",

舉個(gè)例子來說,以下參數(shù)設(shè)置了新生代用Parallel Copying Collector,老生代采用CMS收集器

java -server -Xms512m -Xmx512m  -XX:NewSize=64m -XX:MaxNewSize=64m -XX:SurvivorRatio=2         -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 

此時(shí)需要注意兩個(gè)問題:

如果沒有指定-XX:+UseParNewGC,則采用默認(rèn)的非并行版本的copy collector.

2  如果在一個(gè)單CPU的系統(tǒng)上設(shè)置了-XX:+UseParNewGC ,則默認(rèn)還是采用缺省的copy collector.

3.2.1 控制并行的線程數(shù)

默認(rèn)情況下,Parallel copy collector啟動(dòng)和CPU數(shù)量一樣的線程,也可以通過參數(shù)-XX:ParallelGCThreads來指定,比如你想用3個(gè)線程去進(jìn)行并發(fā)的復(fù)制收集,那么可以改變上述參數(shù)如下:

java -server -Xms512m -Xmx512m -XX:NewSize=64m  -XX:MaxNewSize=64m -XX:SurvivorRatio=2        -XX:ParallelGCThreads=4    -XX:+UseConcMarkSweepGC       -XX:+UseParNewGC 

3.2.2 控制并發(fā)收集的臨界值

默認(rèn)情況下,CMS gc"old generation"空間占用率高于68%的時(shí)候,就會進(jìn)行垃圾收集,而如果想控制收集的臨界值,可以通過參數(shù):-XX:CMSInitiatingOccupancyFraction來控制,比如改變上述的JVM配置如下:

java -server -Xms512m -Xmx512m -XX:NewSize=64m  -XX:MaxNewSize=64m -XX:SurvivorRatio=2        -XX:ParallelGCThreads=4    -XX:+UseConcMarkSweepGC       -XX:+UseParNewGC      -XX:CMSInitiatingOccupancyFraction=35

 

四 GC觸發(fā)以及常見的內(nèi)存錯(cuò)誤

4.1 Minor GC的觸發(fā)

Minor GC主要負(fù)責(zé)收集Young Generation,Minor GC一般在新生代不夠用的情況下觸發(fā),比如我們一次性創(chuàng)建了很多對象等。

List<byte[]> buffer = new ArrayList<byte[]>(); for(int i=0;i<8*1024;i++){

buffer.add(new byte[1024]);

}

以上代碼通過一個(gè)字節(jié)數(shù)組的List模擬觸發(fā)Minor gc,設(shè)置JVM參數(shù)如下:

-verbose:gc -Xmn10M -Xms64M -Xmx64M -XX:+PrintGC

設(shè)置以上參數(shù)以后,因?yàn)?span style="FONT-FAMILY: Times New Roman">-Xmn=10M,默認(rèn)-XX:SurvivorRatio=8 ,則eden的空間大小為8M,當(dāng)eden對象大小超過8M的時(shí)候就會觸發(fā)Minor gc.

運(yùn)行的結(jié)果如下:

[GC 8192K->8030K(64512K), 0.0243391 secs]

從運(yùn)行結(jié)果可以看出,gc前和gc后的eden區(qū)的占用情況,需要注意的是括號里(64512)這個(gè)數(shù)值時(shí)63M,它不包括一塊Survivor 空間。

這里需要注意的一點(diǎn)就是,如果創(chuàng)建的對象大于eden的大小,那么將不會通過Survivor空間復(fù)制,直接轉(zhuǎn)移到old generation.

調(diào)整以上代碼如下:

List<byte[]> buffer = new ArrayList<byte[]>();

buffer.add(new byte[8*1024*1024]);

通過同樣的JVM參數(shù)運(yùn)行,則發(fā)現(xiàn)不會觸發(fā)Minor gc,這是因?yàn)閷ο蟪^了eden的大小,從而直接分配到了Old generation.

 

4.2 Major GC的觸發(fā)

4.2.1 Old Generation空間滿或者接近某一個(gè)比例

Old generation 空間滿是因?yàn)?/span>Young generation提升到Old generation的對象+Old generation的本來的大小已經(jīng)接近或者超過了Old generation的大小。對于CMS GC,當(dāng)Old generation空間使用率接近某一個(gè)比例,可以通過參數(shù)-XX:CMS InitialingOccupancyFraction,此參數(shù)表示Old generation的使用率,默認(rèn)為68%

Young generation對象提升到Old generation對象有以下三種情況:

Ø 分配的對象大于eden空間的大小

Ø Young generation代中經(jīng)過了-XX:MaxTenuringThreshold次復(fù)制任然存活的對象

Ø Minor gc的時(shí)候,放不進(jìn)to survivor的對象

當(dāng)Major GC以后,如果還沒有足夠的空間可以用的話,此時(shí)就會拋出java.lang.OutOfMemoryjava heap space,當(dāng)出現(xiàn)此錯(cuò)誤的時(shí)候,說明可能存在內(nèi)存泄露現(xiàn)象的,這時(shí)候就需要我們對程序進(jìn)行檢查看看什么地方存在內(nèi)存泄露的。

我們可以通過以下代碼來模擬一下java.lang.OutOfMemory:java heap space的發(fā)生:

List<byte[]> buffer = new ArrayList<byte[]>();

buffer.add(new byte[10*1024*1024]);

以上代碼分配了一個(gè)10M的字節(jié)數(shù)組,我們通過以下的參數(shù)運(yùn)行:

-verbose:gc -Xmn10M -Xms20M -Xmx20M -XX:+PrintGC

以上參數(shù)指定Young generation的空間大小為10M,Old generation空間大小為10M。

運(yùn)行結(jié)果如下:

[GC 327K->134K(19456K), 0.0056516 secs]

[Full GC 134K->134K(19456K), 0.0178891 secs]

[Full GC 134K->131K(19456K), 0.0141412 secs]

Exception in thread "main" java.lang.OutOfMemoryError:   Java heap space

        at Test.main(Test.java:30)

從運(yùn)行結(jié)果可以看出,JVM進(jìn)行了一次Minor gc和兩次的Major gc,從Major gc的輸出可以看出,gc以后old區(qū)使用率為134K,而字節(jié)數(shù)組為10M,加起來大于了old generation的空間,所以拋出了異常,如果調(diào)整-Xms21M,-Xmx21M,那么就不會觸發(fā)gc操作也不會出現(xiàn)異常了。

4.2.2 Perm Generation 空間滿

Perm Generation空間主要存放Class對象,Field,Method對象,當(dāng)一次性加載太多的類或者在熱部署以后不卸載類的情況(比如在Jboss服務(wù)器中,如果經(jīng)常熱部署一些應(yīng)用就會出現(xiàn)Perm 空間溢出)就會造成Perm Generation被占滿,此時(shí)就會出現(xiàn):

java.lang.OutOfMemory:PermGen space,在出現(xiàn)此異常的時(shí)候,如果是因?yàn)闊岵渴鹨鸬模覀冎匦聠?dòng)AS就可以了,如果是因?yàn)榧虞d的類太多,此時(shí)可以通過-XX:PermSize-XX:MaxPermSize調(diào)整。

4.3 常見內(nèi)存錯(cuò)誤分析

4.3.1 StackOverflowError 

java.lang.StackOverflowError錯(cuò)誤表示JVM棧溢出,出現(xiàn)這個(gè)錯(cuò)誤的原因一般都是遞歸的層次太深,或者無限的遞歸造成的。出現(xiàn)這種錯(cuò)誤的時(shí)候首先要對應(yīng)用程序進(jìn)行檢查,看看是那些代碼造成了棧溢出,如果是遞歸造成的可以改為迭代方式實(shí)現(xiàn)。

JVM同樣也提供了一個(gè)參數(shù)來讓我們調(diào)節(jié)運(yùn)行時(shí)棧空間的大小。-XX:Xss=256K表示棧空間最大為256K.我們也可以調(diào)大,但是建議不要對此參數(shù)進(jìn)行調(diào)節(jié)。

4.3.2 OutOfMemoryError: Java heap space.

java.lang.OutOfMemoryError: Java heap space這個(gè)錯(cuò)誤表示JVM的新生代和老生代的內(nèi)存不足。出現(xiàn)這個(gè)錯(cuò)誤說明應(yīng)用程序出現(xiàn)了內(nèi)存溢出或者程序所需要的內(nèi)存大于JVM的內(nèi)存設(shè)置了。

遇到這個(gè)問題的時(shí)候,首先我們可以調(diào)節(jié)JVMHeap內(nèi)存的大小,具體可以通過-Xmx -Xms來進(jìn)行設(shè)置,如果設(shè)置大以后還是會出現(xiàn)內(nèi)存溢出,那么說明應(yīng)用程序本身存在內(nèi)存泄露,這個(gè)時(shí)候就需要我們對應(yīng)用程序進(jìn)行檢查,找出導(dǎo)致內(nèi)存泄露的地方,然后修正。

4.3.3 OutOfMemory:PermGen space

java.lang.OutOfMemory:PermGen space錯(cuò)誤是由Perm space空間不足。一般出現(xiàn)這個(gè)錯(cuò)誤是由加載了太多的類或者大量使用了動(dòng)態(tài)代理造成的。如果出現(xiàn)了這個(gè)錯(cuò)誤,我們可以將Perm空間調(diào)大一點(diǎn)。

-XX:PermSize=16M  -XX:MaxPermSize=64M

 

參考資料

1 http://developers.sun.com/mobility/midp/articles/garbage/

2 http://developers.sun.com/mobility/midp/articles/garbagecollection2/

3 http://blogs.sun.com/watt/resource/jvm-options-list.html

4 http://java.sun.com/developer/technicalArticles/Programming/turbo/

5 http://www.ibm.com/developerworks/library/j-jtp10283/index.html?S_TACT=105AGX52&S_CMP=cn-a-j

6 http://www.ibm.com/developerworks/library/j-jtp11253/index.html?S_TACT=105AGX52&S_CMP=cn-a-j

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Tomcat 調(diào)優(yōu)及 JVM 參數(shù)優(yōu)化
JVM 詳解,大白話帶你認(rèn)識 JVM
JVM優(yōu)化配置(轉(zhuǎn))
Java的垃圾回收機(jī)制詳解和調(diào)優(yōu) --燎原
JVM參數(shù)查看與設(shè)置
JVM參數(shù)調(diào)優(yōu)八大技巧
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服