Tomcat性能調(diào)優(yōu)-JVM監(jiān)控與調(diào)優(yōu)(轉(zhuǎn))

參數(shù)設(shè)置

在Java虛擬機(jī)的參數(shù)中,有3種表示方法用“ps -ef |grep "java"命令,可以得到當(dāng)前Java進(jìn)程的所有啟動(dòng)參數(shù)和配置參數(shù):

標(biāo)準(zhǔn)參數(shù)(-),所有的JVM實(shí)現(xiàn)都必須實(shí)現(xiàn)這些參數(shù)的功能,而且向后兼容;

非標(biāo)準(zhǔn)參數(shù)(-X),默認(rèn)jvm實(shí)現(xiàn)這些參數(shù)的功能,但是并不保證所有jvm實(shí)現(xiàn)都滿足,且不保證向后兼容;

非Stable參數(shù)(-XX),此類參數(shù)各個(gè)jvm實(shí)現(xiàn)會(huì)有所不同,將來(lái)可能會(huì)隨時(shí)取消,需要慎重使用(但是,這些參數(shù)往往是非常有用的);

(額外的,-DpropertyName=“value”的形式定義了一些全局屬性值,下面有介紹。)

本文只重點(diǎn)介紹一些重要和常用的參數(shù),如果想了解全部參數(shù),可以參考下面的文章:

Java HotSpot VM Options

Java 6 JVM參數(shù)選項(xiàng)大全(中文版)》(上面一篇的中文版)

JVM啟動(dòng)參數(shù)大全

標(biāo)準(zhǔn)參數(shù)

其實(shí)標(biāo)準(zhǔn)參數(shù)是用過(guò)Java的人都最熟悉的,就是你在運(yùn)行java命令時(shí)后面加上的參數(shù),如java -version, java -jar 等,輸入命令java -help或java -?就能獲得當(dāng)前機(jī)器所有java的標(biāo)準(zhǔn)參數(shù)列表。

-client

設(shè)置jvm使用client模式,這是一般在pc機(jī)器上使用的模式,啟動(dòng)很快,但性能和內(nèi)存管理效率并不高;多用于桌面應(yīng)用;

-server

使用server模式,啟動(dòng)速度雖然慢(比client模式慢10%左右),但是性能和內(nèi)存管理效率很高,適用于服務(wù)器,用于生成環(huán)境、開發(fā)環(huán)境或測(cè)試環(huán)境的服務(wù)端;

如果沒有指定-server或-client,JVM啟動(dòng)的時(shí)候會(huì)自動(dòng)檢測(cè)當(dāng)前主機(jī)是否為服務(wù)器,如果是就以server模式啟動(dòng),64位的JVM只有server模式,所以無(wú)法使用-client參數(shù);

默認(rèn)情況下,不同的啟動(dòng)模式,執(zhí)行GC的方式有所區(qū)別:

啟動(dòng)模式新生代GC方式舊生代和持久代GC的方式

client串行串行

server并行并發(fā)

如果沒有指定-server或-client模式,則判斷方法如下:

-classpath / -cp

JVM加載和搜索文件的目錄路徑,多個(gè)路徑用;分隔。注意,如果使用了-classpath,JVM就不會(huì)再搜索環(huán)境變量中定義的CLASSPATH路徑。

JVM搜索路徑的順序?yàn)椋?/p>

1,先搜索JVM自帶的jar或zip包(Bootstrat,搜索路徑可以用System.getProperty("sun.boot.class.path")獲得);

2,搜索JRE_HOME/lib/ext下的jar包(Extension,搜索路徑可以用System.getProperty("java.ext.dirs")獲得);

3,搜索用戶自定義目錄,順序?yàn)椋寒?dāng)前目錄(.),CLASSPATH,-cp;(搜索路徑用System.getProperty("java.class.path")獲得)

-DpropertyName=value

定義系統(tǒng)的全局屬性值,如配置文件地址等,如果value有空格,可以用-Dname="space string"這樣的形式來(lái)定義,用System.getProperty("propertyName")可以獲得這些定義的屬性值,在代碼中也可以用System.setProperty("propertyName","value")的形式來(lái)定義屬性。

-verbose

這是查詢GC問題最常用的命令之一,具體參數(shù)如:

-verbose:class

輸出jvm載入類的相關(guān)信息,當(dāng)jvm報(bào)告說(shuō)找不到類或者類沖突時(shí)可此進(jìn)行診斷。

-verbose:gc

輸出每次GC的相關(guān)情況,后面會(huì)有更詳細(xì)的介紹。

-verbose:jni

輸出native方法調(diào)用的相關(guān)情況,一般用于診斷jni調(diào)用錯(cuò)誤信息。

非標(biāo)準(zhǔn)參數(shù)

非標(biāo)準(zhǔn)參數(shù),是在標(biāo)準(zhǔn)參數(shù)的基礎(chǔ)上進(jìn)行擴(kuò)展的參數(shù),輸入“java -X”命令,能夠獲得當(dāng)前JVM支持的所有非標(biāo)準(zhǔn)參數(shù)列表(你會(huì)發(fā)現(xiàn),其實(shí)并不多哦)。

在不同類型的JVM中,采用的參數(shù)有所不同,

在講解非標(biāo)準(zhǔn)參數(shù)時(shí),請(qǐng)參考下面的圖,對(duì)內(nèi)存區(qū)域的大小有個(gè)形象的了解(下圖出自:http://iamzhongyong.iteye.com/blog/1333100):

-Xmn

新生代內(nèi)存大小的最大值,包括E區(qū)和兩個(gè)S區(qū)的總和,使用方法如:-Xmn65535,-Xmn1024k,-Xmn512m,-Xmn1g (-Xms,-Xmx也是種寫法)

-Xmn只能使用在JDK1.4或之后的版本中,(之前的1.3/1.4版本中,可使用-XX:NewSize設(shè)置年輕代大小,用-XX:MaxNewSize設(shè)置年輕代最大值);

如果同時(shí)設(shè)置了-Xmn和-XX:NewSize,-XX:MaxNewSize,則誰(shuí)設(shè)置在后面,誰(shuí)就生效;如果同時(shí)設(shè)置了-XX:NewSize -XX:MaxNewSize與-XX:NewRatio則實(shí)際生效的值是:min(MaxNewSize,max(NewSize, heap/(NewRatio+1)))(看考:http://www.open-open.com/home/space.php?uid=71669&do=blog&id=8891)

在開發(fā)、測(cè)試環(huán)境,可以-XX:NewSize 和 -XX:MaxNewSize來(lái)設(shè)置新生代大小,但在線上生產(chǎn)環(huán)境,使用-Xmn一個(gè)即可(推薦),或者將-XX:NewSize 和 -XX:MaxNewSize設(shè)置為同一個(gè)值,這樣能夠防止在每次GC之后都要調(diào)整堆的大小(即:抖動(dòng),抖動(dòng)會(huì)嚴(yán)重影響性能)

-Xms

初始堆的大小,也是堆大小的最小值,默認(rèn)值是總共的物理內(nèi)存/64(且小于1G),默認(rèn)情況下,當(dāng)堆中可用內(nèi)存小于40%(這個(gè)值可以用-XX: MinHeapFreeRatio 調(diào)整,如-X:MinHeapFreeRatio=30)時(shí),堆內(nèi)存會(huì)開始增加,一直增加到-Xmx的大小;

-Xmx

堆的最大值,默認(rèn)值是總共的物理內(nèi)存/64(且小于1G),如果Xms和Xmx都不設(shè)置,則兩者大小會(huì)相同,默認(rèn)情況下,當(dāng)堆中可用內(nèi)存大于70%(這個(gè)值可以用-XX: MaxHeapFreeRatio 調(diào)整,如-X:MaxHeapFreeRatio=60)時(shí),堆內(nèi)存會(huì)開始減少,一直減小到-Xms的大小;

整個(gè)堆的大小=年輕代大小+年老代大小,堆的大小不包含持久代大小,如果增大了年輕代,年老代相應(yīng)就會(huì)減小,官方默認(rèn)的配置為年老代大小/年輕代大小=2/1左右(使用-XX:NewRatio可以設(shè)置-XX:NewRatio=5,表示年老代/年輕代=5/1);

建議在開發(fā)測(cè)試環(huán)境可以用Xms和Xmx分別設(shè)置最小值最大值,但是在線上生產(chǎn)環(huán)境,Xms和Xmx設(shè)置的值必須一樣,原因與年輕代一樣——防止抖動(dòng);

-Xss

這個(gè)參數(shù)用于設(shè)置每個(gè)線程的棧內(nèi)存,默認(rèn)1M,一般來(lái)說(shuō)是不需要改的。除非代碼不多,可以設(shè)置的小點(diǎn),另外一個(gè)相似的參數(shù)是-XX:ThreadStackSize,這兩個(gè)參數(shù)在1.6以前,都是誰(shuí)設(shè)置在后面,誰(shuí)就生效;1.6版本以后,-Xss設(shè)置在后面,則以-Xss為準(zhǔn),-XXThreadStackSize設(shè)置在后面,則主線程以-Xss為準(zhǔn),其它線程以-XX:ThreadStackSize為準(zhǔn)。

-Xrs

減少JVM對(duì)操作系統(tǒng)信號(hào)(OS Signals)的使用(JDK1.3.1之后才有效),當(dāng)此參數(shù)被設(shè)置之后,jvm將不接收控制臺(tái)的控制handler,以防止與在后臺(tái)以服務(wù)形式運(yùn)行的JVM沖突(這個(gè)用的比較少,參考:http://www.blogjava.net/midstr/archive/2008/09/21/230265.html)。

-Xprof

跟蹤正運(yùn)行的程序,并將跟蹤數(shù)據(jù)在標(biāo)準(zhǔn)輸出輸出;適合于開發(fā)環(huán)境調(diào)試。

-Xnoclassgc

關(guān)閉針對(duì)class的gc功能;因?yàn)槠渥柚箖?nèi)存回收,所以可能會(huì)導(dǎo)致OutOfMemoryError錯(cuò)誤,慎用;

-Xincgc

開啟增量gc(默認(rèn)為關(guān)閉);這有助于減少長(zhǎng)時(shí)間GC時(shí)應(yīng)用程序出現(xiàn)的停頓;但由于可能和應(yīng)用程序并發(fā)執(zhí)行,所以會(huì)降低CPU對(duì)應(yīng)用的處理能力。

-Xloggc:file

與-verbose:gc功能類似,只是將每次GC事件的相關(guān)情況記錄到一個(gè)文件中,文件的位置最好在本地,以避免網(wǎng)絡(luò)的潛在問題。

若與verbose命令同時(shí)出現(xiàn)在命令行中,則以-Xloggc為準(zhǔn)。

非Stable參數(shù)(非靜態(tài)參數(shù))

以-XX表示的非Stable參數(shù),雖然在官方文檔中是不確定的,不健壯的,各個(gè)公司的實(shí)現(xiàn)也各有不同,但往往非常實(shí)用,所以這部分參數(shù)對(duì)于GC非常重要。JVM(Hotspot)中主要的參數(shù)可以大致分為3類(參考http://blog.csdn.net/sfdev/article/details/2063928):

性能參數(shù)( Performance Options):用于JVM的性能調(diào)優(yōu)和內(nèi)存分配控制,如初始化內(nèi)存大小的設(shè)置;

行為參數(shù)(Behavioral Options):用于改變JVM的基礎(chǔ)行為,如GC的方式和算法的選擇;

調(diào)試參數(shù)(Debugging Options):用于監(jiān)控、打印、輸出等jvm參數(shù),用于顯示jvm更加詳細(xì)的信息;

比較詳細(xì)的非Stable參數(shù)總結(jié),請(qǐng)參考Java 6 JVM參數(shù)選項(xiàng)大全(中文版)

對(duì)于非Stable參數(shù),使用方法有4種:

-XX:+ 啟用選項(xiàng)

-XX:- 不啟用選項(xiàng)

-XX:= 給選項(xiàng)設(shè)置一個(gè)數(shù)字類型值,可跟單位,例如 32k, 1024m, 2g

-XX:= 給選項(xiàng)設(shè)置一個(gè)字符串值,例如-XX:HeapDumpPath=./dump.core

首先介紹性能參數(shù),性能參數(shù)往往用來(lái)定義內(nèi)存分配的大小和比例,相比于行為參數(shù)和調(diào)試參數(shù),一個(gè)比較明顯的區(qū)別是性能參數(shù)后面往往跟的有數(shù)值,常用如下:

參數(shù)及其默認(rèn)值描述

-XX:NewSize=2.125m

新生代對(duì)象生成時(shí)占用內(nèi)存的默認(rèn)值

-XX:MaxNewSize=size新生成對(duì)象能占用內(nèi)存的最大值

-XX:MaxPermSize=64m方法區(qū)所能占用的最大內(nèi)存(非堆內(nèi)存)

-XX:PermSize=64m方法區(qū)分配的初始內(nèi)存

-XX:MaxTenuringThreshold=15

對(duì)象在新生代存活區(qū)切換的次數(shù)(堅(jiān)持過(guò)MinorGC的次數(shù),每堅(jiān)持過(guò)一次,該值就增加1),大于該值會(huì)進(jìn)入老年代

-XX:MaxHeapFreeRatio=70

GC后java堆中空閑量占的最大比例,大于該值,則堆內(nèi)存會(huì)減少

-XX:MinHeapFreeRatio=40GC后java堆中空閑量占的最小比例,小于該值,則堆內(nèi)存會(huì)增加

-XX:NewRatio=2新生代內(nèi)存容量與老生代內(nèi)存容量的比例

-XX:ReservedCodeCacheSize= 32m保留代碼占用的內(nèi)存容量

-XX:ThreadStackSize=512設(shè)置線程棧大小,若為0則使用系統(tǒng)默認(rèn)值

-XX:LargePageSizeInBytes=4m設(shè)置用于Java堆的大頁(yè)面尺寸

-XX:PretenureSizeThreshold= size大于該值的對(duì)象直接晉升入老年代(這種對(duì)象少用為好)

-XX:SurvivorRatio=8Eden區(qū)域Survivor區(qū)的容量比值,如默認(rèn)值為8,代表Eden:Survivor1:Survivor2=8:1:1

常用的行為參數(shù),主要用來(lái)選擇使用什么樣的垃圾收集器組合,以及控制運(yùn)行過(guò)程中的GC策略等:

參數(shù)及其默認(rèn)值描述

-XX:-UseSerialGC

啟用串行GC,即采用Serial+Serial Old模式

-XX:-UseParallelGC

啟用并行GC,即采用Parallel Scavenge+Serial Old收集器組合(-Server模式下的默認(rèn)組合)

-XX:GCTimeRatio=99設(shè)置用戶執(zhí)行時(shí)間占總時(shí)間的比例(默認(rèn)值99,即1%的時(shí)間用于GC)

-XX:MaxGCPauseMillis=time設(shè)置GC的最大停頓時(shí)間(這個(gè)參數(shù)只對(duì)Parallel Scavenge有效)

-XX:+UseParNewGC使用ParNew+Serial Old收集器組合

-XX:ParallelGCThreads設(shè)置執(zhí)行內(nèi)存回收的線程數(shù),在+UseParNewGC的情況下使用

-XX:+UseParallelOldGC

使用Parallel Scavenge +Parallel Old組合收集器

-XX:+UseConcMarkSweepGC使用ParNew+CMS+Serial Old組合并發(fā)收集,優(yōu)先使用ParNew+CMS,當(dāng)用戶線程內(nèi)存不足時(shí),采用備用方案Serial Old收集。

-XX:-DisableExplicitGC禁止調(diào)用System.gc();但jvm的gc仍然有效

-XX:+ScavengeBeforeFullGC新生代GC優(yōu)先于Full GC執(zhí)行

常用的調(diào)試參數(shù),主要用于監(jiān)控和打印GC的信息:

參數(shù)及其默認(rèn)值描述

-XX:-CITime打印消耗在JIT編譯的時(shí)間

-XX:ErrorFile=./hs_err_pid.log保存錯(cuò)誤日志或者數(shù)據(jù)到文件中

-XX:-ExtendedDTraceProbes開啟solaris特有的dtrace探針

-XX:HeapDumpPath=./java_pid.hprof指定導(dǎo)出堆信息時(shí)的路徑或文件名

-XX:-HeapDumpOnOutOfMemoryError當(dāng)首次遭遇OOM時(shí)導(dǎo)出此時(shí)堆中相關(guān)信息

-XX:OnError=";"出現(xiàn)致命ERROR之后運(yùn)行自定義命令

-XX:OnOutOfMemoryError=";"當(dāng)首次遭遇OOM時(shí)執(zhí)行自定義命令

-XX:-PrintClassHistogram遇到Ctrl-Break后打印類實(shí)例的柱狀信息,與jmap -histo功能相同

-XX:-PrintConcurrentLocks遇到Ctrl-Break后打印并發(fā)鎖的相關(guān)信息,與jstack -l功能相同

-XX:-PrintCommandLineFlags打印在命令行中出現(xiàn)過(guò)的標(biāo)記

-XX:-PrintCompilation當(dāng)一個(gè)方法被編譯時(shí)打印相關(guān)信息

-XX:-PrintGC每次GC時(shí)打印相關(guān)信息

-XX:-PrintGC Details每次GC時(shí)打印詳細(xì)信息

-XX:-PrintGCTimeStamps打印每次GC的時(shí)間戳

-XX:-TraceClassLoading跟蹤類的加載信息

-XX:-TraceClassLoadingPreorder跟蹤被引用到的所有類的加載信息

-XX:-TraceClassResolution跟蹤常量池

-XX:-TraceClassUnloading跟蹤類的卸載信息

-XX:-TraceLoaderConstraints跟蹤類加載器約束的相關(guān)信息

再次聲明,上面的三種參數(shù),主要參考了博客:http://blog.csdn.net/sfdev/article/details/2063928和http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm,后一個(gè)比較全面,有興趣的可以仔細(xì)研讀。

這些參數(shù)將為我們進(jìn)行GC的監(jiān)控與調(diào)優(yōu)提供很大助力,是我們進(jìn)行GC相關(guān)操作的重要工具。

收集器搭配

在介紹了常用的配置參數(shù)之后,我們將開始真正的JVM實(shí)操征程,首先,我們要為應(yīng)用程序選擇一個(gè)合適的垃圾收集器組合,本節(jié)請(qǐng)參考《Java系列筆記(3) - Java 內(nèi)存區(qū)域和GC機(jī)制》一文中的“垃圾收集器”一節(jié),及上節(jié)中的行為參數(shù)。

這里需要再次引用這幅圖(圖來(lái)源于《深入理解Java虛擬機(jī):JVM高級(jí)特效與最佳實(shí)現(xiàn)》,圖中兩個(gè)收集器之間有連線,說(shuō)明它們可以配合使用):

Serial收集器:Serial收集器是在client模式下默認(rèn)的新生代收集器,其收集效率大約是100M左右的內(nèi)存需要幾十到100多毫秒;在client模式下,收集桌面應(yīng)用的內(nèi)存垃圾,基本上不影響用戶體驗(yàn)。所以,一般的Java桌面應(yīng)用中,直接使用Serial收集器(不需要配置參數(shù),用默認(rèn)即可)。

ParNew收集器:Serial收集器的多線程版本,這種收集器默認(rèn)開通的線程數(shù)與CPU數(shù)量相同,-XX:ParallelGCThreads可以用來(lái)設(shè)置開通的線程數(shù)。

可以與CMS收集器配合使用,事實(shí)上用-XX:+UseConcMarkSweepGC選擇使用CMS收集器時(shí),默認(rèn)使用的就是ParNew收集器,所以不需要額外設(shè)置-XX:+UseParNewGC,設(shè)置了也不會(huì)沖突,因?yàn)闀?huì)將ParNew+Serial Old作為一個(gè)備選方案;

如果單獨(dú)使用-XX:+UseParNewGC參數(shù),則選擇的是ParNew+Serial Old收集器組合收集器。

一般情況下,在server模式下,如果選擇CMS收集器,則優(yōu)先選擇ParNew收集器。

Parallel Scavenge收集器:關(guān)注的是吞吐量(關(guān)于吞吐量的含義見上一篇博客),可以這么理解,關(guān)注吞吐量,意味著強(qiáng)調(diào)任務(wù)更快的完成,而如CMS等關(guān)注停頓時(shí)間短的收集器,強(qiáng)調(diào)的是用戶交互體驗(yàn)。

在需要關(guān)注吞吐量的場(chǎng)合,比如數(shù)據(jù)運(yùn)算服務(wù)器等,就可以使用Parallel Scavenge收集器。

老年代收集器如下:

Serial Old收集器:在1.5版本及以前可以與 Parallel Scavenge結(jié)合使用(事實(shí)上,也是當(dāng)時(shí)Parallel Scavenge唯一能用的版本),另外就是在使用CMS收集器時(shí)的備用方案,發(fā)生 Concurrent Mode Failure時(shí)使用。

如果是單獨(dú)使用,Serial Old一般用在client模式中。

Parallel Old收集器:在1.6版本之后,與 Parallel Scavenge結(jié)合使用,以更好的貫徹吞吐量?jī)?yōu)先的思想,如果是關(guān)注吞吐量的服務(wù)器,建議使用Parallel Scavenge + Parallel Old 收集器。

CMS收集器:這是當(dāng)前階段使用很廣的一種收集器,國(guó)內(nèi)很多大的互聯(lián)網(wǎng)公司線上服務(wù)器都使用這種垃圾收集器(http://blog.csdn.net/wisgood/article/details/17067203),筆者公司的收集器也是這種,CMS收集器以獲取最短回收停頓時(shí)間為目標(biāo),非常適合對(duì)用戶響應(yīng)比較高的B/S架構(gòu)服務(wù)器。

CMSIncrementalMode:CMS收集器變種,屬增量式垃圾收集器,在并發(fā)標(biāo)記和并發(fā)清理時(shí)交替運(yùn)行垃圾收集器和用戶線程。

G1 收集器:面向服務(wù)器端應(yīng)用的垃圾收集器,計(jì)劃未來(lái)替代CMS收集器。

一般來(lái)說(shuō),如果是Java桌面應(yīng)用,建議采用Serial+Serial Old收集器組合,即:-XX:+UseSerialGC(-client下的默認(rèn)參數(shù))

在開發(fā)/測(cè)試環(huán)境,可以采用默認(rèn)參數(shù),即采用Parallel Scavenge+Serial Old收集器組合,即:-XX:+UseParallelGC(-server下的默認(rèn)參數(shù))

在線上運(yùn)算優(yōu)先的環(huán)境,建議采用Parallel Scavenge+Serial Old收集器組合,即:-XX:+UseParallelGC

在線上服務(wù)響應(yīng)優(yōu)先的環(huán)境,建議采用ParNew+CMS+Serial Old收集器組合,即:-XX:+UseConcMarkSweepGC

另外在選擇了垃圾收集器組合之后,還要配置一些輔助參數(shù),以保證收集器可以更好的工作。關(guān)于這些參數(shù),請(qǐng)?jiān)趆ttp://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm中查詢其意義和用法,如:

選用了ParNew收集器,你可能需要配置4個(gè)參數(shù): -XX:SurvivorRatio, -XX:PretenureSizeThreshold, -XX:+HandlePromotionFailure,-XX:MaxTenuringThreshold;

選用了 Parallel Scavenge收集器,你可能需要配置3個(gè)參數(shù): -XX:MaxGCPauseMillis,-XX:GCTimeRatio, -XX:+UseAdaptiveSizePolicy ;

選用了CMS收集器,你可能需要配置3個(gè)參數(shù): -XX:CMSInitiatingOccupancyFraction, -XX:+UseCMSCompactAtFullCollection, -XX:CMSFullGCsBeforeCompaction;

啟動(dòng)內(nèi)存分配

關(guān)于GC有一個(gè)常見的疑問是,在啟動(dòng)時(shí),我的內(nèi)存如何分配?經(jīng)過(guò)前面的學(xué)習(xí),已經(jīng)很容易知道,用-Xmn,-Xmx,-Xms,-Xss,-XX:NewSize,-XX:MaxNewSize,-XX:MaxPermSize,-XX:PermSize,-XX:SurvivorRatio,-XX:PretenureSizeThreshold,-XX:MaxTenuringThreshold就基本可以配置內(nèi)存啟動(dòng)時(shí)的分配情況。但是,具體配置多少?設(shè)置小了,頻繁GC(甚至內(nèi)存溢出),設(shè)置大了,內(nèi)存浪費(fèi)。結(jié)合前面對(duì)于內(nèi)存區(qū)域和其作用的學(xué)習(xí),盡量考慮如下建議:

-XX:PermSize盡量比-XX:MaxPermSize小,-XX:MaxPermSize>= 2 * -XX:PermSize, -XX:PermSize> 64m,一般對(duì)于4G內(nèi)存的機(jī)器,-XX:MaxPermSize不會(huì)超過(guò)256m;

-Xms =? -Xmx(線上Server模式),以防止抖動(dòng),大小受操作系統(tǒng)和內(nèi)存大小限制,如果是32位系統(tǒng),則一般-Xms設(shè)置為1g-2g(假設(shè)有4g內(nèi)存),在64位系統(tǒng)上,沒有限制,不過(guò)一般為機(jī)器最大內(nèi)存的一半左右;

-Xmn,在開發(fā)環(huán)境下,可以用-XX:NewSize和-XX:MaxNewSize來(lái)設(shè)置新生代的大小(-XX:NewSize<=-XX:MaxNewSize),在生產(chǎn)環(huán)境,建議只設(shè)置-Xmn,一般-Xmn的大小是-Xms的1/2左右,不要設(shè)置的過(guò)大或過(guò)小,過(guò)大導(dǎo)致老年代變小,頻繁Full GC,過(guò)小導(dǎo)致minor GC頻繁。如果不設(shè)置-Xmn,可以采用-XX:NewRatio=2來(lái)設(shè)置,也是一樣的效果;

-Xss一般是不需要改的,默認(rèn)值即可。

-XX:SurvivorRatio一般設(shè)置8-10左右,推薦設(shè)置為10,也即:Survivor區(qū)的大小是Eden區(qū)的1/10,一般來(lái)說(shuō),普通的Java程序應(yīng)用,一次minorGC后,至少98%-99%的對(duì)象,都會(huì)消亡,所以,survivor區(qū)設(shè)置為Eden區(qū)的1/10左右,能使Survivor區(qū)容納下10-20次的minor GC才滿,然后再進(jìn)入老年代,這個(gè)與 -XX:MaxTenuringThreshold的默認(rèn)值15次也相匹配的。如果XX:SurvivorRatio設(shè)置的太小,會(huì)導(dǎo)致本來(lái)能通過(guò)minor回收掉的對(duì)象提前進(jìn)入老年代,產(chǎn)生不必要的full gc;如果XX:SurvivorRatio設(shè)置的太大,會(huì)導(dǎo)致Eden區(qū)相應(yīng)的被壓縮。

-XX:MaxTenuringThreshold默認(rèn)為15,也就是說(shuō),經(jīng)過(guò)15次Survivor輪換(即15次minor GC),就進(jìn)入老年代, 如果設(shè)置的小的話,則年輕代對(duì)象在survivor中存活的時(shí)間減小,提前進(jìn)入年老代,對(duì)于年老代比較多的應(yīng)用,可以提高效率。如果將此值設(shè)置為一個(gè)較大值,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制,這樣可以增加對(duì)象在年輕代的存活時(shí)間,增加在年輕代即被回收的概率。需要注意的是,設(shè)置了 -XX:MaxTenuringThreshold,并不代表著,對(duì)象一定在年輕代存活15次才被晉升進(jìn)入老年代,它只是一個(gè)最大值,事實(shí)上,存在一個(gè)動(dòng)態(tài)計(jì)算機(jī)制,計(jì)算每次晉入老年代的閾值,取閾值和MaxTenuringThreshold中較小的一個(gè)為準(zhǔn)。

-XX:PretenureSizeThreshold一般采用默認(rèn)值即可。

監(jiān)控工具和方法

在JVM運(yùn)行的過(guò)程中,為保證其穩(wěn)定、高效,或在出現(xiàn)GC問題時(shí)分析問題原因,我們需要對(duì)GC進(jìn)行監(jiān)控。所謂監(jiān)控,其實(shí)就是分析清楚當(dāng)前GC的情況。其目的是鑒別JVM是否在高效的進(jìn)行垃圾回收,以及有沒有必要進(jìn)行調(diào)優(yōu)。

通過(guò)監(jiān)控GC,我們可以搞清楚很多問題,如:

1,minor GC和full GC的頻率;

2,執(zhí)行一次GC所消耗的時(shí)間;

3,新生代的對(duì)象何時(shí)被移到老生代以及花費(fèi)了多少時(shí)間;

4,每次GC中,其它線程暫停(Stop the world)的時(shí)間;

5,每次GC的效果如何,是否不理想;

………………

監(jiān)控GC的工具分為2種:命令行工具和圖形工具;

常用的命令行工具有:

注:下面的命令都在JAVA_HOME/bin中,是java自帶的命令。如果您發(fā)現(xiàn)無(wú)法使用,請(qǐng)直接進(jìn)入Java安裝目錄調(diào)用或者先設(shè)置Java的環(huán)境變量,一個(gè)簡(jiǎn)單的辦法為:直接運(yùn)行命令 export PATH=$JAVA_HOME/bin:$PATH;另外,一般的,在Linux下,下面的命令需要sudo權(quán)限,在windows下,部分命令的部分選項(xiàng)不能使用。

1,jps

jps命令用于查詢正在運(yùn)行的JVM進(jìn)程,常用的參數(shù)為:

-q:只輸出LVMID,省略主類的名稱

-m:輸出虛擬機(jī)進(jìn)程啟動(dòng)時(shí)傳給主類main()函數(shù)的參數(shù)

-l:輸出主類的全類名,如果進(jìn)程執(zhí)行的是Jar包,輸出Jar路徑

-v:輸出虛擬機(jī)進(jìn)程啟動(dòng)時(shí)JVM參數(shù)

命令格式:jps [option] [hostid]

一個(gè)簡(jiǎn)單的例子:

在上圖中,有一個(gè)vid為309的apache進(jìn)程在提供web服務(wù)。

2,jstat

jstat可以實(shí)時(shí)顯示本地或遠(yuǎn)程JVM進(jìn)程中類裝載、內(nèi)存、垃圾收集、JIT編譯等數(shù)據(jù)(如果要顯示遠(yuǎn)程JVM信息,需要遠(yuǎn)程主機(jī)開啟RMI支持)。如果在服務(wù)啟動(dòng)時(shí)沒有指定啟動(dòng)參數(shù)-verbose:gc,則可以用jstat實(shí)時(shí)查看gc情況。

jstat有如下選項(xiàng):

-class:監(jiān)視類裝載、卸載數(shù)量、總空間及類裝載所耗費(fèi)的時(shí)間

-gc:監(jiān)聽Java堆狀況,包括Eden區(qū)、兩個(gè)Survivor區(qū)、老年代、永久代等的容量,以用空間、GC時(shí)間合計(jì)等信息

-gccapacity:監(jiān)視內(nèi)容與-gc基本相同,但輸出主要關(guān)注java堆各個(gè)區(qū)域使用到的最大和最小空間

-gcutil:監(jiān)視內(nèi)容與-gc基本相同,但輸出主要關(guān)注已使用空間占總空間的百分比

-gccause:與-gcutil功能一樣,但是會(huì)額外輸出導(dǎo)致上一次GC產(chǎn)生的原因

-gcnew:監(jiān)視新生代GC狀況

-gcnewcapacity:監(jiān)視內(nèi)同與-gcnew基本相同,輸出主要關(guān)注使用到的最大和最小空間

-gcold:監(jiān)視老年代GC情況

-gcoldcapacity:監(jiān)視內(nèi)同與-gcold基本相同,輸出主要關(guān)注使用到的最大和最小空間

-gcpermcapacity:輸出永久代使用到最大和最小空間

-compiler:輸出JIT編譯器編譯過(guò)的方法、耗時(shí)等信息

-printcompilation:輸出已經(jīng)被JIT編譯的方法

命令格式:jstat [option vmid [interval[s|ms] [count]]]

jstat可以監(jiān)控遠(yuǎn)程機(jī)器,命令格式中VMID和LVMID特別說(shuō)明:如果是本地虛擬機(jī)進(jìn)程,VMID和LVMID是一致的,如果是遠(yuǎn)程虛擬機(jī)進(jìn)程,那么VMID格式是: [protocol:][//]lvmid[@hostname[:port]/servername],如果省略interval和count,則只查詢一次

查看gc情況的例子:

在圖中,命令sudo jstat -gc 309 1000 5代表著:搜集vid為309的java進(jìn)程的整體gc狀態(tài), 每1000ms收集一次,共收集5次;XXXC表示該區(qū)容量,XXXU表示該區(qū)使用量,各列解釋如下:

S0C:S0區(qū)容量(S1區(qū)相同,略)

S0U:S0區(qū)已使用

EC:E區(qū)容量

EU:E區(qū)已使用

OC:老年代容量

OU:老年代已使用

PC:Perm容量

PU:Perm區(qū)已使用

YGC:Young GC(Minor GC)次數(shù)

YGCT:Young GC總耗時(shí)

FGC:Full GC次數(shù)

FGCT:Full GC總耗時(shí)

GCT:GC總耗時(shí)

用gcutil查看內(nèi)存的例子:

圖中的各列與用gc參數(shù)時(shí)基本一致,不同的是這里顯示的是已占用的百分比,如S0為86.53,代表著S0區(qū)已使用了86.53%

3,jinfo

用于查詢當(dāng)前運(yùn)行這的JVM屬性和參數(shù)的值。

jinfo可以使用如下選項(xiàng):

-flag:顯示未被顯示指定的參數(shù)的系統(tǒng)默認(rèn)值

-flag [+|-]name或-flag name=value: 修改部分參數(shù)

-sysprops:打印虛擬機(jī)進(jìn)程的System.getProperties()

命令格式:jinfo [option] pid

4,jmap

用于顯示當(dāng)前Java堆和永久代的詳細(xì)信息(如當(dāng)前使用的收集器,當(dāng)前的空間使用率等)

-dump:生成java堆轉(zhuǎn)儲(chǔ)快照

-heap:顯示java堆詳細(xì)信息(只在Linux/Solaris下有效)

-F:當(dāng)虛擬機(jī)進(jìn)程對(duì)-dump選項(xiàng)沒有響應(yīng)時(shí),可使用這個(gè)選項(xiàng)強(qiáng)制生成dump快照(只在Linux/Solaris下有效)

-finalizerinfo:顯示在F-Queue中等待Finalizer線程執(zhí)行finalize方法的對(duì)象(只在Linux/Solaris下有效)

-histo:顯示堆中對(duì)象統(tǒng)計(jì)信息

-permstat:以ClassLoader為統(tǒng)計(jì)口徑顯示永久代內(nèi)存狀態(tài)(只在Linux/Solaris下有效)

命令格式:jmap [option] vmid

其中前面3個(gè)參數(shù)最重要,如:

查看對(duì)詳細(xì)信息:sudo jmap -heap 309

生成dump文件: sudo jmap -dump:file=./test.prof 309

部分用戶沒有權(quán)限時(shí),采用admin用戶:sudo -u admin -H? jmap -dump:format=b,file=文件名.hprof pid

查看當(dāng)前堆中對(duì)象統(tǒng)計(jì)信息:sudo? jmap -histo 309:該命令顯示3列,分別為對(duì)象數(shù)量,對(duì)象大小,對(duì)象名稱,通過(guò)該命令可以查看是否內(nèi)存中有大對(duì)象;

有的用戶可能沒有jmap權(quán)限:sudo -u admin -H jmap -histo 309 | less

5,jhat

用于分析使用jmap生成的dump文件,是JDK自帶的工具,使用方法為: jhat -J -Xmx512m [file]

不過(guò)jhat沒有mat好用,推薦使用mat(Eclipse插件: http://www.eclipse.org/mat ),mat速度更快,而且是圖形界面。

6,jstack

用于生成當(dāng)前JVM的所有線程快照,線程快照是虛擬機(jī)每一條線程正在執(zhí)行的方法,目的是定位線程出現(xiàn)長(zhǎng)時(shí)間停頓的原因。

-F:當(dāng)正常輸出的請(qǐng)求不被響應(yīng)時(shí),強(qiáng)制輸出線程堆棧

-l:除堆棧外,顯示關(guān)于鎖的附加信息

-m:如果調(diào)用到本地方法的話,可以顯示C/C++的堆棧

命令格式:jstack [option] vmid

7,-verbosegc

-verbosegc是一個(gè)比較重要的啟動(dòng)參數(shù),記錄每次gc的日志,下面的表格對(duì)比了jstat和-verbosegc:

jstat-verbosegc

監(jiān)控對(duì)象

運(yùn)行在本機(jī)的Java應(yīng)用可以把日志輸出到終端上,或者借助jstatd命令通過(guò)網(wǎng)絡(luò)連接遠(yuǎn)程的Java應(yīng)用。

只有那些把-verbogc作為啟動(dòng)參數(shù)的JVM。

輸出信息

堆狀態(tài)(已用空間,最大限制,GC執(zhí)行次數(shù)/時(shí)間,等等)

執(zhí)行GC前后新生代和老年代空間大小,GC執(zhí)行時(shí)間。

輸出時(shí)間

Every designated time

每次設(shè)定好的時(shí)間。每次GC發(fā)生的時(shí)候。

用途觀察堆空間變化情況

了解單次GC產(chǎn)生的效果。

與-verbosegc配合使用的一些常用參數(shù)為:

-XX:+PrintGCDetails,打印GC信息,這是-verbosegc默認(rèn)開啟的選項(xiàng)

-XX:+PrintGCTimeStamps,打印每次GC的時(shí)間戳

-XX:+PrintHeapAtGC:每次GC時(shí),打印堆信息

-XX:+PrintGCDateStamps (from JDK 6 update 4) :打印GC日期,適合于長(zhǎng)期運(yùn)行的服務(wù)器

-Xloggc:/home/admin/logs/gc.log:制定打印信息的記錄的日志位置

每條verbosegc打印出的gc日志,都類似于下面的格式:

time [GC [: -> (total occupancy1), secs] -> (total occupancy3), secs]

如:

這些選項(xiàng)的意義是:

time:執(zhí)行GC的時(shí)間,需要添加-XX:+PrintGCDateStamps參數(shù)才有;

collector:minor gc使用的收集器的名字。

starting occupancy1:GC執(zhí)行前新生代空間大小。

ending occupancy1:GC執(zhí)行后新生代空間大小。

total occupancy1:新生代總大小

pause time1:因?yàn)閳?zhí)行minor GC,Java應(yīng)用暫停的時(shí)間。

starting occupancy3:GC執(zhí)行前堆區(qū)域總大小

ending occupancy3:GC執(zhí)行后堆區(qū)域總大小

total occupancy3:堆區(qū)總大小

pause time3:Java應(yīng)用由于執(zhí)行堆空間GC(包括full GC)而停止的時(shí)間。

8,可視化工具

監(jiān)控和分析GC也有一些可視化工具,比較常見的有JConsole和VisualVM,有興趣的可以看看下面的文章,在此不再贅述:

http://blog.csdn.net/java2000_wl/article/details/8049707

調(diào)優(yōu)方法

一切都是為了這一步,調(diào)優(yōu),在調(diào)優(yōu)之前,我們需要記住下面的原則:

多數(shù)的Java應(yīng)用不需要在服務(wù)器上進(jìn)行GC優(yōu)化;

多數(shù)導(dǎo)致GC問題的Java應(yīng)用,都不是因?yàn)槲覀儏?shù)設(shè)置錯(cuò)誤,而是代碼問題;

在應(yīng)用上線之前,先考慮將機(jī)器的JVM參數(shù)設(shè)置到最優(yōu)(最適合);

減少創(chuàng)建對(duì)象的數(shù)量;

減少使用全局變量和大對(duì)象;

GC優(yōu)化是到最后不得已才采用的手段;

在實(shí)際使用中,分析GC情況優(yōu)化代碼比優(yōu)化GC參數(shù)要多得多;

GC優(yōu)化的目的有兩個(gè)(http://www.360doc.com/content/13/0305/10/15643_269388816.shtml):

將轉(zhuǎn)移到老年代的對(duì)象數(shù)量降低到最小;

減少full GC的執(zhí)行時(shí)間;

為了達(dá)到上面的目的,一般地,你需要做的事情有:

減少使用全局變量和大對(duì)象;

調(diào)整新生代的大小到最合適;

設(shè)置老年代的大小為最合適;

選擇合適的GC收集器;

在上面的4條方法中,用了幾個(gè)“合適”,那究竟什么才算合適,一般的,請(qǐng)參考上面“收集器搭配”和“啟動(dòng)內(nèi)存分配”兩節(jié)中的建議。但這些建議不是萬(wàn)能的,需要根據(jù)您的機(jī)器和應(yīng)用情況進(jìn)行發(fā)展和變化,實(shí)際操作中,可以將兩臺(tái)機(jī)器分別設(shè)置成不同的GC參數(shù),并且進(jìn)行對(duì)比,選用那些確實(shí)提高了性能或減少了GC時(shí)間的參數(shù)。

真正熟練的使用GC調(diào)優(yōu),是建立在多次進(jìn)行GC監(jiān)控和調(diào)優(yōu)的實(shí)戰(zhàn)經(jīng)驗(yàn)上的,進(jìn)行監(jiān)控和調(diào)優(yōu)的一般步驟為:

1,監(jiān)控GC的狀態(tài)

使用各種JVM工具,查看當(dāng)前日志,分析當(dāng)前JVM參數(shù)設(shè)置,并且分析當(dāng)前堆內(nèi)存快照和gc日志,根據(jù)實(shí)際的各區(qū)域內(nèi)存劃分和GC執(zhí)行時(shí)間,覺得是否進(jìn)行優(yōu)化;

2,分析結(jié)果,判斷是否需要優(yōu)化

如果各項(xiàng)參數(shù)設(shè)置合理,系統(tǒng)沒有超時(shí)日志出現(xiàn),GC頻率不高,GC耗時(shí)不高,那么沒有必要進(jìn)行GC優(yōu)化;如果GC時(shí)間超過(guò)1-3秒,或者頻繁GC,則必須優(yōu)化;

注:如果滿足下面的指標(biāo),則一般不需要進(jìn)行GC:

Minor GC執(zhí)行時(shí)間不到50ms;

Minor GC執(zhí)行不頻繁,約10秒一次;

Full GC執(zhí)行時(shí)間不到1s;

Full GC執(zhí)行頻率不算頻繁,不低于10分鐘1次;

3,調(diào)整GC類型和內(nèi)存分配

如果內(nèi)存分配過(guò)大或過(guò)小,或者采用的GC收集器比較慢,則應(yīng)該優(yōu)先調(diào)整這些參數(shù),并且先找1臺(tái)或幾臺(tái)機(jī)器進(jìn)行beta,然后比較優(yōu)化過(guò)的機(jī)器和沒有優(yōu)化的機(jī)器的性能對(duì)比,并有針對(duì)性的做出最后選擇;

4,不斷的分析和調(diào)整

通過(guò)不斷的試驗(yàn)和試錯(cuò),分析并找到最合適的參數(shù)

5,全面應(yīng)用參數(shù)

如果找到了最合適的參數(shù),則將這些參數(shù)應(yīng)用到所有服務(wù)器,并進(jìn)行后續(xù)跟蹤。

調(diào)優(yōu)實(shí)例

上面的內(nèi)容都是紙上談兵,下面我們以一些真實(shí)例子來(lái)進(jìn)行說(shuō)明:

實(shí)例1:

筆者昨日發(fā)現(xiàn)部分開發(fā)測(cè)試機(jī)器出現(xiàn)異常:java.lang.OutOfMemoryError: GC overhead limit exceeded,這個(gè)異常代表:GC為了釋放很小的空間卻耗費(fèi)了太多的時(shí)間,其原因一般有兩個(gè):1,堆太小,2,有死循環(huán)或大對(duì)象;

筆者首先排除了第2個(gè)原因,因?yàn)檫@個(gè)應(yīng)用同時(shí)是在線上運(yùn)行的,如果有問題,早就掛了。所以懷疑是這臺(tái)機(jī)器中堆設(shè)置太小;

使用ps -ef |grep "java"查看,發(fā)現(xiàn):

該應(yīng)用的堆區(qū)設(shè)置只有768m,而機(jī)器內(nèi)存有2g,機(jī)器上只跑這一個(gè)java應(yīng)用,沒有其他需要占用內(nèi)存的地方。另外,這個(gè)應(yīng)用比較大,需要占用的內(nèi)存也比較多;

筆者通過(guò)上面的情況判斷,只需要改變堆中各區(qū)域的大小設(shè)置即可,于是改成下面的情況:

跟蹤運(yùn)行情況發(fā)現(xiàn),相關(guān)異常沒有再出現(xiàn);

實(shí)例2:(http://www.360doc.com/content/13/0305/10/15643_269388816.shtml)

一個(gè)服務(wù)系統(tǒng),經(jīng)常出現(xiàn)卡頓,分析原因,發(fā)現(xiàn)Full GC時(shí)間太長(zhǎng):

jstat -gcutil:

S0???? S1??? E???? O?????? P??????? YGC YGCT FGC FGCT? GCT

12.16 0.00 5.18 63.78 20.32? 54?? 2.047 5???? 6.946? 8.993

分析上面的數(shù)據(jù),發(fā)現(xiàn)Young GC執(zhí)行了54次,耗時(shí)2.047秒,每次Young GC耗時(shí)37ms,在正常范圍,而Full GC執(zhí)行了5次,耗時(shí)6.946秒,每次平均1.389s,數(shù)據(jù)顯示出來(lái)的問題是:Full GC耗時(shí)較長(zhǎng),分析該系統(tǒng)的是指發(fā)現(xiàn),NewRatio=9,也就是說(shuō),新生代和老生代大小之比為1:9,這就是問題的原因:

1,新生代太小,導(dǎo)致對(duì)象提前進(jìn)入老年代,觸發(fā)老年代發(fā)生Full GC;

2,老年代較大,進(jìn)行Full GC時(shí)耗時(shí)較大;

優(yōu)化的方法是調(diào)整NewRatio的值,調(diào)整到4,發(fā)現(xiàn)Full GC沒有再發(fā)生,只有Young GC在執(zhí)行。這就是把對(duì)象控制在新生代就清理掉,沒有進(jìn)入老年代(這種做法對(duì)一些應(yīng)用是很有用的,但并不是對(duì)所有應(yīng)用都要這么做)

實(shí)例3:

一應(yīng)用在性能測(cè)試過(guò)程中,發(fā)現(xiàn)內(nèi)存占用率很高,F(xiàn)ull GC頻繁,使用sudo -u admin -H? jmap -dump:format=b,file=文件名.hprof pid 來(lái)dump內(nèi)存,生成dump文件,并使用Eclipse下的mat差距進(jìn)行分析,發(fā)現(xiàn):

從圖中可以看出,這個(gè)線程存在問題,隊(duì)列LinkedBlockingQueue所引用的大量對(duì)象并未釋放,導(dǎo)致整個(gè)線程占用內(nèi)存高達(dá)378m,此時(shí)通知開發(fā)人員進(jìn)行代碼優(yōu)化,將相關(guān)對(duì)象釋放掉即可。


參考資料

原文:http://blog.chinaunix.net/uid-26204366-id-3896703.html

《深入理解Java虛擬機(jī):JVM高級(jí)特效與最佳實(shí)現(xiàn)》

JVM啟動(dòng)參數(shù)大全, http://www.blogjava.net/midstr/archive/2008/09/21/230265.html

JVM系列三:JVM參數(shù)設(shè)置、分析, http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html

Java 6 JVM參數(shù)選項(xiàng)大全(中文版), http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm

成為JavaGC專家Part II — 如何監(jiān)控Java垃圾回收機(jī)制, http://www.importnew.com/2057.html

成為Java GC專家系列(3) — 如何優(yōu)化Java垃圾回收機(jī)制, http://www.importnew.com/3146.html

JDK5.0垃圾收集優(yōu)化之--Don't Pause, http://calvin.iteye.com/blog/91905

Java HOTSPOT VM參數(shù)大全, http://tech.sina.com.cn/s/2009-09-23/09561077572.shtml

【原】GC的默認(rèn)方式, http://iamzhongyong.iteye.com/blog/1447314

JAVA啟動(dòng)參數(shù)大全之三:非Stable參數(shù), http://blog.csdn.net/sfdev/article/details/2063928

Java虛擬機(jī)學(xué)習(xí) - 內(nèi)存調(diào)優(yōu), http://blog.csdn.net/java2000_wl/article/details/8090940

內(nèi)存溢出, http://www.open-open.com/home/space.php?uid=71669&do=blog&id=8891

如何查看JVM的擴(kuò)展參數(shù):-X, http://www.blogjava.net/beansoft/archive/2012/03/01/371088.html

JVM內(nèi)存狀況查看方法和分析工具, http://hi.baidu.com/kingfly666666/item/e710a4371c60b0f1e7bb7a32

虛擬機(jī)學(xué)習(xí)系列 - 附 - 虛擬機(jī)參數(shù), http://blog.csdn.net/su1216/article/details/7780924

JVM系列四:生產(chǎn)環(huán)境參數(shù)實(shí)例及分析【生產(chǎn)環(huán)境實(shí)例增加中】, http://www.cnblogs.com/redcreen/archive/2011/05/05/2038331.html

垃圾收集器與內(nèi)存分配策略, http://raging-sweet.iteye.com/blog/1170198

JVM垃圾收集器使用調(diào)查:CMS最受歡迎 , http://blog.csdn.net/wisgood/article/details/17067203

Xms Xmx PermSize MaxPermSize 區(qū)別, http://www.cnblogs.com/mingforyou/archive/2012/03/03/2378143.html

Java虛擬機(jī)學(xué)習(xí) - JDK可視化監(jiān)控工具, http://blog.csdn.net/java2000_wl/article/details/8049707

虛擬機(jī)學(xué)習(xí)系列 - 6 - JDK工具, http://blog.csdn.net/su1216/article/details/7780857

JVM監(jiān)控工具介紹jstack, jconsole, jinfo, jmap, jdb, jstat, http://hi.baidu.com/lotusxyhf/item/9cd8fcb8d6f8c1a5ebba935b

JVM 與 jstat, http://blog.sina.com.cn/s/blog_56fcfd620100hdcp.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評(píng)論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,778評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,436評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,795評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,993評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,229評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,687評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,990評(píng)論 2 374

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

  • 1.一些概念 1.1.數(shù)據(jù)類型 Java虛擬機(jī)中,數(shù)據(jù)類型可以分為兩類:基本類型和引用類型。基本類型的變量保存原始...
    落落落落大大方方閱讀 4,555評(píng)論 4 86
  • Tomcat 的缺省配置是不能穩(wěn)定長(zhǎng)期運(yùn)行的,也就是不適合生產(chǎn)環(huán)境,它會(huì)死機(jī),讓你不斷重新啟動(dòng),甚至在午夜時(shí)分喚醒...
    憤怒的_菜鳥閱讀 2,131評(píng)論 0 24
  • 最近工作中,老是遇到程序假死或者宕掉,最終原因都是full gc導(dǎo)致,剛好回過(guò)頭再學(xué)習(xí)一下JVM內(nèi)存模式,以及GC...
    VIPSHOP_FCS閱讀 1,740評(píng)論 0 4
  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,385評(píng)論 1 56
  • 開放會(huì)讓你不舒服。在小世界里也許很厲害,只要你一進(jìn)入開放系統(tǒng),就馬上能看到許多比你強(qiáng)的人。有以前完全看不到的強(qiáng)人,...
    仰慕兒閱讀 278評(píng)論 0 0