• <em id="6vhwh"><rt id="6vhwh"></rt></em>

    <style id="6vhwh"></style>

    <style id="6vhwh"></style>
    1. <style id="6vhwh"></style>
        <sub id="6vhwh"><p id="6vhwh"></p></sub>
        <p id="6vhwh"></p>
          1. 国产亚洲欧洲av综合一区二区三区 ,色爱综合另类图片av,亚洲av免费成人在线,久久热在线视频精品视频,成在人线av无码免费,国产精品一区二区久久毛片,亚洲精品成人片在线观看精品字幕 ,久久亚洲精品成人av秋霞

            jdk1.5(jdk15.0.2是什么版本)

            更新時間:2023-03-01 14:02:06 閱讀: 評論:0

            JDK 17 之 JVM調(diào)優(yōu) 史詩級 教程文章目錄JDK 17 之 JVM調(diào)優(yōu) 史詩級 教程3.6.3 其他收集器適用場景4.1.2 如何產(chǎn)生dump文件4.1.2.1 JVM的配置文件中配置4.1.2.3 第三方可視化工具生成4.5 對比調(diào)優(yōu)前后指標(biāo)差異5.8.1 如何啟動JConsole5.8.2 如何設(shè)置JAVA程序運(yùn)行時可以被JConsol連接分析6.4.1 -XX:+PrintFlagsInitial、-XX:+PrintFlagsFinal6.4.2 -XX:+PrintCommandLineFlags6.4.4 -XX:CMSFullGCsBeforeCompaction6.4.5 -XX:HeapDumpPath6.4.6 -XX:OnOutOfMemoryError6.4.7 XX:InitialCodeCacheSize6.4.8 -XX:+UCodeCacheFlushing1 調(diào)優(yōu)層次

            性能調(diào)優(yōu)包含多個層次,比如:架構(gòu)調(diào)優(yōu)、代碼調(diào)優(yōu)、JVM調(diào)優(yōu)、數(shù)據(jù)庫調(diào)優(yōu)、操作系統(tǒng)調(diào)優(yōu)等。 架構(gòu)調(diào)優(yōu)和代碼調(diào)優(yōu)是JVM調(diào)優(yōu)的基礎(chǔ),其中架構(gòu)調(diào)優(yōu)是對系統(tǒng)影響最大的。

            2 調(diào)優(yōu)指標(biāo)吞吐量:運(yùn)行用戶代碼的時間占總運(yùn)行時間的行例 (總運(yùn)行時間=程序的運(yùn)行時間+內(nèi)存回收的時間);暫停時間:執(zhí)行垃圾收集時,程序的工作線程被暫停的時間;內(nèi)存占用:java堆區(qū)所占的內(nèi)存大??;

            這三者共同構(gòu)成一個“不可能三角”。三者總體的表現(xiàn)會隨著技術(shù)進(jìn)步而越來越好。一款優(yōu)秀的收集器通常最多同時滿足其中的兩項。

            簡單來說,主要抓住兩點(diǎn):

            吞吐量 吞吐量優(yōu)先,意味著在單位時間內(nèi),STW的時間最短暫停時間 暫停時間優(yōu)先,意味這盡可能讓單次STW的時間最短

            在設(shè)計(或使用)GC算法時,必須確定我們的目標(biāo):一個GC算法只可能針對兩個目標(biāo)之一(即只專注于較大吞吐量或最小暫停時間),或嘗試找一個二者的折衷。

            現(xiàn)在標(biāo)準(zhǔn),在最大吞吐量優(yōu)先的情況下,降低停頓時間。3 JVM調(diào)優(yōu)原則3.1 優(yōu)先原則

            優(yōu)先架構(gòu)調(diào)優(yōu)和代碼調(diào)優(yōu),JVM優(yōu)化是不得已的手段,大多數(shù)的Java應(yīng)用不需要進(jìn)行JVM優(yōu)化

            3.2 堆設(shè)置

            參數(shù)-Xms和-Xmx,通常設(shè)置為相同的值,避免運(yùn)行時要不斷擴(kuò)展JVM內(nèi)存,建議擴(kuò)大至3-4倍FullGC后的老年代空間占用。

            3.3 年輕代設(shè)置

            參數(shù)-Xmn,1-1.5倍FullGC之后的老年代空間占用。

            避免新生代設(shè)置過小,當(dāng)新生代設(shè)置過小時,會帶來兩個問題:一是minor GC次數(shù)頻繁,二是可能導(dǎo)致 minor GC對象直接進(jìn)老年代。當(dāng)老年代內(nèi)存不足時,會觸發(fā)Full GC。 避免新生代設(shè)置過大,當(dāng)新生代設(shè)置過大時,會帶來兩個問題:一是老年代變小,可能導(dǎo)致Full GC頻繁執(zhí)行;二是 minor GC 執(zhí)行回收的時間大幅度增加。

            3.4 老年代設(shè)置注重低延遲的應(yīng)用老年代使用并發(fā)收集器,所以其大小需要小心設(shè)置,一般要考慮并發(fā)會話率和會話持續(xù)時間等一些參數(shù)如果堆設(shè)置偏小,可能會造成內(nèi)存碎片、高回收頻率以及應(yīng)用暫停如果堆設(shè)置偏大,則需要較長的收集時間吞吐量優(yōu)先的應(yīng)用 一般吞吐量優(yōu)先的應(yīng)用都有一個較大的年輕代和一個較小的老年代。原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而老年代盡可能存放長期存活對象3.5 方法區(qū)設(shè)置

            基于jdk1.7版本,永久代:參數(shù)-XX:PermSize和-XX:MaxPermSize; 基于jdk1.8版本,元空間:參數(shù) -XX:MetaspaceSize和-XX:MaxMetaspaceSize; 通常設(shè)置為相同的值,避免運(yùn)行時要不斷擴(kuò)展,建議擴(kuò)大至1.2-1.5倍FullGc后的永久帶空間占用。

            3.6 GC設(shè)置3.6.1 GC發(fā)展階段

            SerialParallel(并行) CMS(并發(fā)) G1ZGC 截至jdk1.8 ,一共有7款不同垃圾收集器。每一款不同的垃圾收集器都有不同的特點(diǎn),在具體使用的時候,需要根據(jù)具體的情況選擇不同的垃圾回收器

            3.6.2 G1的適用場景面向服務(wù)端應(yīng)用,針對具有大內(nèi)存、多處理器的機(jī)器。(在普通大小的堆里表現(xiàn)并不驚喜)最主要的應(yīng)用是需要低GC延遲并具有大堆的應(yīng)用程序提供解決方案(G1通過每次只清理一部分而不是全部Region的增量式清理來保證每次GC停頓時間不會過長)在堆大小約6GB或更大時,可預(yù)測的暫停時間可以低于0.5秒用來替換掉JDK1.5中的CMS收集器,以下情況,使用G1可能比CMS好超過50% 的java堆被活動數(shù)據(jù)占用對象分配頻率或年代提升頻率變化很大GC停頓時間過長(大于0.5至1秒)從經(jīng)驗上來說,整體而言:小內(nèi)存應(yīng)用上,CMS大概率會優(yōu)于 G1;大內(nèi)存應(yīng)用上,G1則很可能更勝一籌。 這個臨界點(diǎn)大概是在 6~8G 之間(經(jīng)驗值)3.6.3 其他收集器適用場景如果你想要最小化地使用內(nèi)存和并行開銷,請選擇Serial Old(老年代) + Serial(年輕代)如果你想要最大化應(yīng)用程序的吞吐量,請選擇Parallel Old(老年代) + Parallel(年輕代)如果你想要最小化GC的中斷或停頓時間,請選擇CMS(老年代) + ParNew(年輕代)4 JVM調(diào)優(yōu)步驟4.1 監(jiān)控分析

            分析GC日志及dump文件,判斷是否需要優(yōu)化,確定瓶頸問題點(diǎn)。

            4.1.1 如何生成GC日志

            常用參數(shù)部分會詳細(xì)講解如何生成GC日志

            4.1.2 如何產(chǎn)生dump文件4.1.2.1 JVM的配置文件中配置

            JVM啟動時增加兩個參數(shù):

            # 出現(xiàn)OOME時生成堆dump:-XX:+HeapDumpOnOutOfMemoryError# 生成堆文件地址:-XX:HeapDumpPath=/home/hadoop/dump/4.1.2.2 jmap生成

            發(fā)現(xiàn)程序異常前通過執(zhí)行指令,直接生成當(dāng)前JVM的dump文件

            jmap -dump:file=文件名.dump [pid]# 9257是指JVM的進(jìn)程號jmap -dump:format=b,file=testmap.dump 9257

            第一種方式是一種事后方式,需要等待當(dāng)前JVM出現(xiàn)問題后才能生成dump文件,實時性不高; 第二種方式在執(zhí)行時,JVM是暫停服務(wù)的,所以對線上的運(yùn)行會產(chǎn)生影響。

            所以建議第一種方式。

            4.1.2.3 第三方可視化工具生成4.2 判斷

            如果各項參數(shù)設(shè)置合理,系統(tǒng)沒有超時日志或異常信息出現(xiàn),GC頻率不高,GC耗時不高,那么沒有必要進(jìn)行GC優(yōu)化,如果GC時間超過1-3秒,或者頻繁GC,則必須優(yōu)化。 遇到以下情況,就需要考慮進(jìn)行JVM調(diào)優(yōu):

            系統(tǒng)吞吐量與響應(yīng)性能不高或下降;Heap內(nèi)存(老年代)持續(xù)上漲達(dá)到設(shè)置的最大內(nèi)存值;Full GC 次數(shù)頻繁;GC 停頓時間過長(超過1秒);應(yīng)用出現(xiàn)OutOfMemory等內(nèi)存異常;應(yīng)用中有使用本地緩存且占用大量內(nèi)存空間;4.3 確定目標(biāo)

            調(diào)優(yōu)的最終目的都是為了應(yīng)用程序使用最小的硬件消耗來承載更大的吞吐量或者低延遲。 jvm調(diào)優(yōu)主要是針對垃圾收集器的收集性能優(yōu)化,減少GC的頻率和Full GC的次數(shù),令運(yùn)行在虛擬機(jī)上的應(yīng)用能夠使用更少的內(nèi)存、高吞吐量、低延遲。

            下面列舉一些JVM調(diào)優(yōu)的量化目標(biāo)參考實例,注意:不同應(yīng)用的JVM調(diào)優(yōu)量化目標(biāo)是不一樣的。

            堆內(nèi)存使用率<=70%;老年代內(nèi)存使用率<=70%;avgpau<=1秒;Full GC次數(shù)0或avg pau interval>=24小時 ;4.4 調(diào)整參數(shù)

            調(diào)優(yōu)一般是從滿足程序的內(nèi)存使用需求開始的,之后是時間延遲的要求,最后才是吞吐量的要求。 要基于這個步驟來不斷優(yōu)化,每一個步驟都是進(jìn)行下一步的基礎(chǔ),不可逆行之。

            4.5 對比調(diào)優(yōu)前后指標(biāo)差異4.6 重復(fù)以上過程4.7 應(yīng)用

            找到合適的參數(shù),先在單臺服務(wù)器上試運(yùn)行,然后將這些參數(shù)應(yīng)用到所有服務(wù)器,并進(jìn)行后續(xù)跟蹤。

            5 JVM調(diào)優(yōu)工具5.1 jps

            jps:JVM Process Status Tool jps可以查看Java進(jìn)程,相當(dāng)于Linux下的ps命令,只不過它只列出Java進(jìn)程。

            5.1.1 使用語法

            jps:列出Java程序進(jìn)程ID和Main函數(shù)名稱jps -q:只輸出進(jìn)程IDjps -m:輸出傳遞給Java進(jìn)程(主函數(shù))的參數(shù)jps -l:輸出主函數(shù)的完整路徑j(luò)ps -v:顯示傳遞給Java虛擬的參數(shù)5.1.2 示例

            02.png

            5.2 jstat

            jstat:JVM Statistics Monitoring Tool jstat可以查看Java程序運(yùn)行時相關(guān)信息,可以通過它查看堆信息的相關(guān)情況

            5.2.1 使用語法

            jstat -<options> [-t] [-h<lines>] <vmid> [<interval> [<count>]]5.2.2 options可選值

            -class:顯示ClassLoader的相關(guān)信息-compiler:顯示JIT編譯的相關(guān)信息-gc:顯示與GC相關(guān)信息-gccapacity:顯示各個代的容量和使用情況-gccau:顯示垃圾收集相關(guān)信息(同-gcutil),同時顯示最后一次或當(dāng)前正在發(fā)生的垃圾收集的誘發(fā)原因-gcnew:顯示新生代信息-gcnewcapacity:顯示新生代大小和使用情況-gcold:顯示老年代信息-gcoldcapacity:顯示老年代大小-gcpermcapacity:顯示永久代大小-gcutil:顯示垃圾收集信息-printcompilation:輸出JIT編譯的方法信息-t:在輸出信息前加上一個Timestamp列,顯示程序的運(yùn)行時間-h:可以在周期性數(shù)據(jù)輸出后,輸出多少行數(shù)據(jù)后,跟著一個表頭信息interval:用于指定輸出統(tǒng)計數(shù)據(jù)的周期,單位為毫秒count:用于指定一個輸出多少次數(shù)據(jù)5.2.3 示例

            示例一顯示GC相關(guān)信息

            jstat -gc 7063 500 47063 是進(jìn)程ID ,采樣時間間隔為500ms,采樣數(shù)為4

            03.png

            S0C:年輕代中第一個survivor(幸存區(qū))的容量 (字節(jié))S1C:年輕代中第二個survivor(幸存區(qū))的容量 (字節(jié))S0U:年輕代中第一個survivor(幸存區(qū))目前已使用空間 (字節(jié))S1U:年輕代中第二個survivor(幸存區(qū))目前已使用空間 (字節(jié))EC :年輕代中Eden(伊甸園)的容量 (字節(jié))EU :年輕代中Eden(伊甸園)前已使空間 (字節(jié))OC :Old代的容量 (字節(jié))OU :Old代目前已使用空間 (字節(jié))MC:metaspace(元空間)的容量 (字節(jié))MU:metaspace(元空間)目前已使用空間 (字節(jié))CCSC:壓縮類空間大小CCSU:壓縮類空間使用大小YGC :從應(yīng)用程序啟動到采樣時年輕代中g(shù)c次數(shù)YGCT :從應(yīng)用程序啟動到采樣時年輕代中g(shù)c所用時間(s)FGC :從應(yīng)用程序啟動到采樣時old代(全gc)gc次數(shù)FGCT :從應(yīng)用程序啟動到采樣時old代(全gc)gc所用時間(s)GCT:從應(yīng)用程序啟動到采樣時gc用的總時間(s)

            示例二顯示垃圾收集相關(guān)信息

            jstat -gcutil 7737 5s 5

            04.png

            S0 年輕代中第一個survivor(幸存區(qū))已使用的占當(dāng)前容量百分比S1 年輕代中第二個survivor(幸存區(qū))已使用的占當(dāng)前容量百分比E 年輕代中Eden(伊甸園)已使用的占當(dāng)前容量百分比O old代已使用的占當(dāng)前容量百分比M metaspace已使用的占當(dāng)前容量百分比CCS 壓縮使用比例YGC 從應(yīng)用程序啟動到采樣時年輕代中g(shù)c次數(shù)YGCT 從應(yīng)用程序啟動到采樣時年輕代中g(shù)c所用時間(s)FGC 從應(yīng)用程序啟動到采樣時old代(全gc)gc次數(shù)FGCT 從應(yīng)用程序啟動到采樣時old代(全gc)gc所用時間(s)GCT 從應(yīng)用程序啟動到采樣時gc用的總時間(s)5.3 jinfo

            jinfo:Java Configuration Info jinfo可以用來查看正在運(yùn)行的java程序的擴(kuò)展參數(shù),甚至支持運(yùn)行時修改部分參數(shù)

            5.3.1 使用語法

            jinfo [option] <pid>5.3.2 option可選值

            -flag <name> to print the value of the named VM flag-flag [+|-]<name> to enable or disable the named VM flag-flag <name>=<value> to t the named VM flag to the given value-flags to print VM flags-sysprops to print Java system properties<no option> to print both of the above-h | -help to print this help message5.3.2 示例示例一

            查看堆的最大值

            ~ jinfo -flag MaxHeapSize 8384-XX:MaxHeapSize=10485760示例二

            查看所有參數(shù)

            ~ jinfo -flags 8384Attaching to process ID 8384, plea wait...Debugger attached successfully.Server compiler detected.JVM version is 25.121-b13Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=3145728 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=3145728 -XX:OldSize=7340032 -XX:+UCompresdClassPointers -XX:+UCompresdOops -XX:+UFastUnorderedTimeStamps -XX:+UParallelGCCommand line: -Xms10m -Xmx10m -Dfile.encoding=UTF-8示例三

            查看使用的垃圾回收器

            ~ jinfo -flag UParallelGC 8384-XX:+UParallelGC~ jinfo -flag UConcMarkSweepGC 8384-XX:-UConcMarkSweepGC示例四

            設(shè)置日志打印

            ~ jinfo -flag PrintGCDetails 8384-XX:-PrintGCDetails~ jinfo -flag +PrintGCDetails 8384~ jinfo -flag PrintGCDetails 8384-XX:+PrintGCDetails~ jinfo -flag -PrintGCDetails 8384~ jinfo -flag PrintGCDetails 8384-XX:-PrintGCDetails5.4 jmap

            jmap:Memory Map jmap可以查看堆內(nèi)存使用狀況,一般結(jié)合jhat使用。

            5.4.1 使用語法

            jmap [option] <pid> (to connect to running process) jmap [option] <executable <core> (to connect to a core file) jmap [option] [rver_id@]<remote rver IP or hostname> (to connect to remote debug rver)

            option:選項參數(shù)。 pid:需要打印配置信息的進(jìn)程ID。 executable:產(chǎn)生核心dump的Java可執(zhí)行文件。 core:需要打印配置信息的核心文件。 rver-id:可選的唯一id,如果相同的遠(yuǎn)程主機(jī)上運(yùn)行了多臺調(diào)試服務(wù)器,用此選項參數(shù)標(biāo)識服務(wù)器。 remote rver IP or hostname:遠(yuǎn)程調(diào)試服務(wù)器的IP地址或主機(jī)名。

            5.4.2 option可選值

            <none> to print same info as Solaris pmap-heap to print java heap summary-histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects-clstats to print class loader statistics-finalizerinfo to print information on objects awaiting finalization-dump:<dump-options> to dump java heap in hprof binary format-F force. U with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode.-h | -help to print this help message-J<flag> to pass <flag> directly to the runtime system

            no option: 查看進(jìn)程的內(nèi)存映像信息,類似 Solaris pmap 命令。 heap: 顯示Java堆詳細(xì)信息 histo[:live]: 顯示堆中對象的統(tǒng)計信息 clstats:打印類加載器信息 finalizerinfo: 顯示在F-Queue隊列等待Finalizer線程執(zhí)行finalizer方法的對象 dump::生成堆轉(zhuǎn)儲快照 F:當(dāng)-dump沒有響應(yīng)時,使用-dump或者-histo參數(shù)。在這個模式下,live子參數(shù)無效 help:打印幫助信息 J:指定傳遞給運(yùn)行jmap的JVM的參數(shù)

            dump-options可選值

            -live dump only live objects; if not specified,all objects in the heap are dumped.-format=b binary format-file=<file> dump heap to <file>Example:jmap -dump:live,format=b,file=heap.bin <pid>5.4.3 示例示例一

            顯示Java堆詳細(xì)信息

            jmap -heap pid

            打印一個堆的摘要信息,包括使用的GC算法、堆配置信息和各內(nèi)存區(qū)域內(nèi)存使用信息

            ~ jmap -heap 8985Attaching to process ID 8985, plea wait...Debugger attached successfully.Server compiler detected.JVM version is 25.121-b13using thread-local object allocation.Parallel GC with 8 thread(s)Heap Configuration:MinHeapFreeRatio = 0MaxHeapFreeRatio = 100MaxHeapSize = 524288000 (500.0MB)NewSize = 174587904 (166.5MB)MaxNewSize = 174587904 (166.5MB)OldSize = 349700096 (333.5MB)NewRatio = 2SurvivorRatio = 8MetaspaceSize = 21807104 (20.796875MB)CompresdClassSpaceSize = 1073741824 (1024.0MB)MaxMetaspaceSize = 17592186044415 MBG1HeapRegionSize = 0 (0.0MB)Heap Usage:PS Young GenerationEden Space:capacity = 131596288 (125.5MB)ud = 127090976 (121.20339965820312MB)free = 4505312 (4.296600341796875MB)96.57641407028137% udFrom Space:capacity = 21495808 (20.5MB)ud = 21477712 (20.482742309570312MB)free = 18096 (0.0172576904296875MB)99.91581614424543% udTo Space:capacity = 21495808 (20.5MB)ud = 0 (0.0MB)free = 21495808 (20.5MB)0.0% udPS Old Generationcapacity = 349700096 (333.5MB)ud = 100703528 (96.03836822509766MB)free = 248996568 (237.46163177490234MB)28.79711191157351% ud2156 interned Strings occupying 152440 bytes.示例二

            顯示堆中對象的統(tǒng)計信息

            jmap -histo:live pid

            其中包括每個Java類、對象數(shù)量、內(nèi)存大小(單位:字節(jié))、完全限定的類名。打印的虛擬機(jī)內(nèi)部的類名稱將會帶有一個’*’前綴。如果指定了live子選項,則只計算活動的對象。

            ~ jmap -histo:live 8985 num #instances #bytes class name---------------------------------------------- 1: 3682 339156840 [B 2: 3806 408160 [C 3: 3794 91056 java.lang.String 4: 593 67480 java.lang.Class 5: 587 54568 [Ljava.lang.Object; 6: 3273 52368 com.kkb.example.HeapInstanceTest示例三

            打印類加載器信息

            jmap -clstats pid

            -clstats是-permstat的替代方案,在JDK8之前,-permstat用來打印類加載器的數(shù)據(jù)打印Java堆內(nèi)存的永久保存區(qū)域的類加載器的智能統(tǒng)計信息。對于每個類加載器而言,它的名稱、活躍 度、地址、父類加載器、它所加載的類的數(shù)量和大小都會被打印。此外,包含的字符串?dāng)?shù)量和大小也會被打印。

            ~ jmap -clstats 8985Attaching to process ID 8985, plea wait...Debugger attached successfully.Server compiler detected.JVM version is 25.121-b13finding class loader instances ..done.computing per loader stat ..done.plea wait.. computingliveness...................................................................................................done.class_loader class bytes parent_loader alive? type<bootstrap> 517 969116 null live <internal>0x00000007af095a08 0 0 0x00000007ae86f288 live java/util/ResourceBundle$RBClassLoader@0x00000007c00555e80x00000007ae86f288 9 29861 0x00000007ae8770f8 live sun/misc/Launcher$AppClassLoader@0x00000007c000f6a00x00000007ae8770f8 0 0 null live sun/misc/Launcher$ExtClassLoader@0x00000007c000fa48total = 4 526 998977 N/A alive=4, dead=0 N/A示例四

            打印正等候回收的對象的信息

            jmap -finalizerinfo pid

            ~ jmap -finalizerinfo 10067Attaching to process ID 10067, plea wait...Debugger attached successfully.Server compiler detected.JVM version is 25.121-b13Number of objects pending for finalization: 0

            Number of objects pending for finalization: 0 說明當(dāng)前F-QUEUE隊列中并沒有等待Fializer線程執(zhí)行final

            示例五

            生成堆轉(zhuǎn)儲快照dump文件

            jmap -dump:format=b,file=heapdump.dump pid

            以hprof二進(jìn)制格式轉(zhuǎn)儲Java堆到指定filename的文件中。live子選項是可選的。如果指定了live 子選項,堆中只有活動的對象會被轉(zhuǎn)儲。想要瀏覽heap dump,你可以使用jhat(Java堆分析具)讀取生成的文件。

            這個命令執(zhí)行,JVM會將整個heap的信息dump寫入到個文件,heap如果比較大的話,就會導(dǎo)致這個過程比較耗時,并且執(zhí)行的過程中為了保證dump的信息是可靠的,所以會暫停應(yīng)用, 線上系統(tǒng)慎用。

            ~ jmap -dump:format=b,file=heapdump.dump 10067 Dumping heap to /Urs/hadoop/heapdump.dump ...5.5 jhat

            jhat:Java Heap Analysis Tool

            jhat 命令解析Java堆轉(zhuǎn)儲文件并啟動一個 web rver,然后用瀏覽器來查看、瀏覽 dump 出來的 heap。

            jhat 命令支持預(yù)先設(shè)計的查詢,比如顯示某個類的所有實例。 還支持對象查詢語言(OQL, Object Query Language)。 OQL有點(diǎn)類似SQL,專門用來查詢堆轉(zhuǎn)儲。

            5.5.1 使用語法

            jhat [ options ] heap-dump-file5.5.2 options可選值

            -stack fal|true關(guān)閉對象分配調(diào)用棧跟蹤(tracking object allocation call stack)。 如果分配位置信息在堆轉(zhuǎn)儲中不可用,則必須將此標(biāo)志設(shè)置為 fal。 默認(rèn)值為 true 。-refs fal|true關(guān)閉對象引用跟蹤(tracking of references to objects)。 默認(rèn)值為 true 。 默認(rèn)情況下, 返回的指針是指向其他特定對象的對象,如反向鏈接或輸入引用(referrers or incoming references), 會統(tǒng)計、計算堆中的所有對象。-port port-number設(shè)置 jhat HTTP rver 的端口號。 默認(rèn)值 7000 。-exclude exclude-file指定對象查詢時需要排除的數(shù)據(jù)成員列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么當(dāng)從某個特定對象 Object o 計算可達(dá)的對象列表時, 引用路徑涉及 java.lang.String.value 的都會被排除。-baline exclude-file指定一個基準(zhǔn)堆轉(zhuǎn)儲(baline heap dump)。 在兩個 heap dumps 中有相同 object ID 的對象會被標(biāo)記為不是新的(marked as not being new),其他對象被標(biāo)記為新的(new)。 在比較兩個不同的堆轉(zhuǎn)儲時很有用。-debug int設(shè)置 debug 級別。 0表示不輸出調(diào)試信息。 值越大則表示輸出更詳細(xì)的 debug 信息。-version啟動后只顯示版本信息就退出-h顯示幫助信息并退出。 同 -help-help顯示幫助信息并退出。 同 -h-J< flag >因為jhat命令實際上會啟動一個JVM來執(zhí)行, 通過 -J 可以在啟動JVM時傳入一些啟動參數(shù)。 例如, -J-Xmx512m 則指定運(yùn)行jhat的Java虛擬機(jī)使用的最大堆內(nèi)存為 512 MB。 如果需要使用多個JVM啟動參數(shù),則傳多多個 -Jxxxxxx。5.5.3 示例

            利用jhat分析剛剛jmap輸出的堆文件

            05.png

            這樣就啟動起來了一個簡易的HTTP服務(wù),端口號是7000,嘗試一下用瀏覽器訪問下它,本地的可以通過http://localhost:7000就可以得到這樣的頁面:

            jhat啟動后顯示的html頁面中包含有:All class including platform:顯示出堆中所包含的所有的類Show all members of the roott :從根集能引用到的對象Show instance counts for all class (including platform/excluding platform):顯示平臺包括的所有類的實例數(shù)量Show heap histogram:堆實例的分布表Show finalizer summary:Finalizer 摘要Execute Object Query Language (OQL) query:執(zhí)行對象查詢語句(OQL)

            lect a from [I a where a.length > 256 //查詢長度大于256的數(shù)組5.6 jstack

            jstack:Java Stack Trace

            jstack是java虛擬機(jī)自帶的一種堆棧跟蹤工具。jstack用于生成java虛擬機(jī)當(dāng)前時刻的線程快照。線程快照是當(dāng)前java虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現(xiàn)長時間停頓的原因,如線程間死鎖、死循環(huán)、請求外部資源導(dǎo)致的長時間等待等。 線程出現(xiàn)停頓的時候通過jstack來查看各個線程的調(diào)用堆棧,就可以知道沒有響應(yīng)的線程到底在后臺做什么事情,或者等待什么資源。

            如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發(fā)生問題。另外,jstack工具還可以附屬到正在運(yùn)行的java程序中,看到當(dāng)時運(yùn)行的java程序的java stack和native stack的信息, 如果現(xiàn)在運(yùn)行的java程序呈現(xiàn)hung的狀態(tài),jstack是非常有用的。

            5.6.1 使用語法

            jstack [ option ] pid 查看當(dāng)前時間點(diǎn),指定進(jìn)程的dump堆棧信息。jstack [ option ] pid > 文件 將當(dāng)前時間點(diǎn)的指定進(jìn)程的dump堆棧信息,寫入到指定文件中。注:若該文件不存在,則會自動生成;若該文件存在,則會覆蓋源文件。jstack [ option ] executable core 查看當(dāng)前時間點(diǎn),core文件的dump堆棧信息。jstack [ option ] [rver_id@]<remote rver IP or hostname> 查看當(dāng)前時間點(diǎn),遠(yuǎn)程機(jī)器的dump堆棧信息。5.6.2 option可選值

            -F 強(qiáng)制jstack。當(dāng)進(jìn)程掛起了,此時'jstack [-l] pid'是沒有響應(yīng)的,這時候可使用此參數(shù)來強(qiáng)制打印堆棧信息,一般情況不需要使用。-m 打印java和native c/c++框架的所有棧信息??梢源蛴VM的堆棧,以及Native的棧幀,一般應(yīng)用排查不需要使用。-l 長列表。打印關(guān)于鎖的附加信息。例如屬于java.util.concurrent的ownable synchronizers列表,會使得JVM停頓得久得多(可能會差很多倍,如普通的jstack可能毫秒和次GC沒區(qū)別,加了-l 就是近一秒的時間),-l 建議不要用。一般情況不需要使用。-h or -hel 打印幫助信息

            在thread dump中,要留意下面幾種狀態(tài)

            死鎖,Deadlock(重點(diǎn)關(guān)注)等待資源,Waiting on condition(重點(diǎn)關(guān)注)等待獲取監(jiān)視器,Waiting on monitor entry(重點(diǎn)關(guān)注)阻塞,Blocked(重點(diǎn)關(guān)注)執(zhí)行中,Runnable暫停,Suspended對象等待中,Object.wait() 或 TIMED_WAITING停止,Parked5.6.3 示例示例一

            06.png

            示例二將指定進(jìn)程的當(dāng)前堆棧情況記錄到某個件中

            07.png

            示例三統(tǒng)計線程數(shù)

            [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-gibiH2fE-1660299442837)(https://pics6.baidu.com/feed/203fb80e7bec54e7c75e1edde61b64584ec26a6b.png?token=157827beeb1a3cb378be8639c8d21cae)]

            08.png

            示例四檢測死鎖

            09.png

            10.png

            5.7 hprof

            hprof:Heap/CPU Profiling Tool 能夠展現(xiàn)CPU使用率,統(tǒng)計堆內(nèi)存使用情況。

            J2SE中提供了一個簡單的命令行工具來對java程序的cpu和heap進(jìn)行profiling,叫做HPROF。HPROF實際上是JVM中的一個native的庫,它會在JVM啟動的時候通過命令行參數(shù)來動態(tài)加載,并成為JVM進(jìn)程的一部分。若要在java進(jìn)程啟動的時候使用HPROF,用戶可以通過各種命令行參數(shù)類型來使用HPROF對java進(jìn)程的heap或者(和)cpu進(jìn)行profiling的功能。HPROF產(chǎn)生的profiling數(shù)據(jù)可以是二進(jìn)制的,也可以是文本格式的。這些日志可以用來跟蹤和分析java進(jìn)程的性能問題和瓶頸,解決內(nèi)存使用上不優(yōu)的地方或者程序?qū)崿F(xiàn)上的不優(yōu)之處。二進(jìn)制格式的日志還可以被JVM中的HAT工具來進(jìn)行瀏覽和分析,用以觀察java進(jìn)程的heap中各種類型和數(shù)據(jù)的情況。在J2SE 5.0以后的版本中,HPROF已經(jīng)被并入到一個叫做Java Virtual Machine Tool Interface(JVM TI)中。

            5.7.1 使用語法

            java -agentlib:hprof[=options] ToBeProfiledClassjava -Xrunprof[:options] ToBeProfiledClassjavac -J-agentlib:hprof[=options] ToBeProfiledClass5.7.2 options可選值

            Option Name and Value Description Default--------------------- ----------- -------heap=dump|sites|all heap profiling allcpu=samples|times|old CPU usage offmonitor=y|n monitor contention nformat=a|b text(txt) or binary output afile=<file> write data to file java.hprof[.txt]net=<host>:<port> nd data over a socket offdepth=<size> stack trace depth 4interval=<ms> sample interval in ms 10cutoff=<value> output cutoff point 0.0001lineno=y|n line number in traces? ythread=y|n thread in traces? ndoe=y|n dump on exit? ymsa=y|n Solaris micro state accounting nforce=y|n force output to <file> yverbo=y|n print messages about dumps y

            11.png

            5.7.3 示例官方示例

            CPU Usage Sampling Profiling(cpu=samples)的例子 下面每隔20毫秒采樣CPU消耗信息,堆棧深度為3,生成的profile文件名稱是java.hprof.txt,在當(dāng)前目錄。

            java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello

            CPU Usage Times Profiling(cpu=times)的例子 它相對于CPU Usage Sampling Profile能夠獲得更加細(xì)粒度的CPU消耗信息,能夠細(xì)到每個法調(diào)的開始和結(jié)束,它的實現(xiàn)使用了字節(jié)碼注入技術(shù)(BCI)

            javac -J-agentlib:hprof=cpu=times Hello.java

            Heap Allocation Profiling(heap=sites)的例子

            javac -J-agentlib:hprof=heap=sites Hello.java

            Heap Dump(heap=dump)的例子 它能比上面的Heap Allocation Profiling生成更詳細(xì)的Heap Dump信息:

            javac -J-agentlib:hprof=heap=dump Hello.java雖然在JVM啟動參數(shù)中加入-Xrunprof:heap=sites參數(shù)可以生成CPU/Heap Profile文件,但對JVM性 能影響非常大,不建議在線上服務(wù)器環(huán)境使用。示例一

            統(tǒng)計方法耗時

            class java -agentlib:hprof=cpu=times,interval=10 com.kkb.example.HprofTestDumping CPU usage by timing methods ... done.

            class vim java.hprof.txt

            [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-PRHQa1ZI-1660299442839)(https://pics0.baidu.com/feed/d52a2834349b033b01845d3e7dedc9dbd439bdf6.png?token=6a4bf5d39d2964bae903bb3ac3ec50c2)]

            12.png

            示例二

            生成跟蹤點(diǎn)類所占內(nèi)存百分比

            class java -agentlib:hprof=heap=sites com.kkb.example.HprofTestDumping allocation sites ... done.

            class vim java.hprof.txt

            13.png

            5.8 jconsole

            Jconsole:Java Monitoring and Management Console,Java 5引入,一個內(nèi)置 Java 性能分析器,可以從命令行或在 GUI shell 中運(yùn)行。您可以輕松地使用 JConsole來監(jiān)控 Java 應(yīng)用程序性能和跟蹤Java 中的代碼。

            5.8.1 如何啟動JConsole

            如果是從命令行啟動,使 JDK 在 PATH 上,運(yùn)行 jconsole 即可。 如果從 GUI shell 啟動,找到 JDK 安裝路徑,打開 bin 文件夾,雙擊 jconsole 。

            當(dāng)分析工具彈出時(取決于正在運(yùn)行的 Java 版本以及正在運(yùn)行的 Java 程序數(shù)量),可能會出現(xiàn)一個對話框,要求輸入一個進(jìn)程的 URL 來連接,也可能列出許多不同的本地 Java 進(jìn)程(有時包含JConsole 進(jìn)程本身)來連接。 如下圖所示:想分析哪個程序就雙擊哪個進(jìn)程。

            14.png

            5.8.2 如何設(shè)置JAVA程序運(yùn)行時可以被JConsol連接分析

            本地程序(相對于開啟JConsole的計算機(jī)),無需設(shè)置任何參數(shù)就可以被本地開啟的JConsole連接(Java SE 6開始無需設(shè)置,之前還是需要設(shè)置運(yùn)行時參數(shù) -Dcom.sun.management.jmxremote )

            JConsole如何連接遠(yuǎn)程機(jī)器的JAVA程序?

            jconsole 192.168.0.1:8999

            也可以在已經(jīng)打開的JConsole界面操作,連接新建連接選擇遠(yuǎn)程進(jìn)程輸入遠(yuǎn)程主機(jī)IP和端口號點(diǎn)擊“連接”,如下圖

            15.png

            5.8.3 示例

            示例一進(jìn)入視圖后包括這六個標(biāo)簽:

            Overview: 顯示有關(guān)JVM和監(jiān)視值的概述信息Memory: 顯示內(nèi)存使用信息Threads: 顯示線程使用信息Class: 顯示類裝載信息VM Summary:顯示java VM信息MBeans: 顯示 MBeans

            16.png

            上圖描述有我們需要的信息,同時點(diǎn)擊右鍵可以保存數(shù)據(jù)到CSV文件。

            內(nèi)存頁簽相對于可視化的jstat 命令,用于監(jiān)視受收集器管理的虛擬機(jī)內(nèi)存。

            17.png

            6 JVM參數(shù)

            在JVM調(diào)整過程中,主要是對JVM參數(shù)做的調(diào)整,以下我們介紹主要參數(shù)。JVM參數(shù)有很多,其實我們直接使用默認(rèn)的JVM參數(shù),不去修改都可以滿足大多數(shù)情況。但是如果你想在有限的硬件資源下,部署的系統(tǒng)達(dá)到最大的運(yùn)行效率,那么進(jìn)行相關(guān)的JVM參數(shù)設(shè)置是必不可少的。

            JVM參數(shù)主要分為以下三種:標(biāo)準(zhǔn)參數(shù)、非標(biāo)準(zhǔn)參數(shù)、不穩(wěn)定參數(shù)。

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

            標(biāo)準(zhǔn)參數(shù),顧名思義,標(biāo)準(zhǔn)參數(shù)中包括功能以及輸出的結(jié)果都是很穩(wěn)定的,基本上不會隨著JVM版本的變化而變化。

            標(biāo)準(zhǔn)參數(shù)以-開頭,如:java -version、java -jar等,通過java -help可以查詢所有的標(biāo)準(zhǔn)參數(shù),-help 也是個標(biāo)準(zhǔn)參數(shù)。

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

            非標(biāo)準(zhǔn)參數(shù)以-X開頭,是標(biāo)準(zhǔn)參數(shù)的擴(kuò)展。對應(yīng)前面講的標(biāo)準(zhǔn)化參數(shù),這是非標(biāo)準(zhǔn)化參數(shù)。表示在將來的JVM版本中可能會發(fā)生改變,但是這類以-X開始的參數(shù)變化的比較小。 我們可以通過 Java -X 命令來檢索所有-X 參數(shù)。

            我們可以通過設(shè)置非標(biāo)準(zhǔn)參數(shù)來配置堆的內(nèi)存分配,常用的非標(biāo)準(zhǔn)參數(shù)有:

            -Xmn新生代內(nèi)存的大小,包括Eden區(qū)和兩個Survivor區(qū)的總和,寫法如:-Xmn1024,-Xmn1024k,-Xmn1024m,-Xmn1g 。-Xms堆內(nèi)存的最小值,默認(rèn)值是總內(nèi)存/64(且小于1G)。默認(rèn)情況下,當(dāng)堆中可用內(nèi)存小于40%(這個值可以用-XX: MinHeapFreeRatio 調(diào)整,如-X:MinHeapFreeRatio=30)時,堆內(nèi)存會開始增加,直增加到-Xmx的大小。-Xmx堆內(nèi)存的最大值,默認(rèn)值是總內(nèi)存/4(且小于1G)。默認(rèn)情況下,當(dāng)堆中可用內(nèi)存大于70%(這個值可以用-XX: MaxHeapFreeRatio調(diào)整,如-X:MaxHeapFreeRatio =80)時,堆內(nèi)存會開始減少,一直減小到-Xms的大小。 * 如果Xms和Xmx都不設(shè)置,則兩者大小會相同*-Xss每個線程的棧內(nèi)存,默認(rèn)1M,般來說是不需要改的。-Xrs減少JVM對操作系統(tǒng)信號的使用。-Xprof跟蹤正運(yùn)行的程序,并將跟蹤數(shù)據(jù)在標(biāo)準(zhǔn)輸出輸出。適合于開發(fā)環(huán)境調(diào)試。-Xnoclassgc關(guān)閉針對class的gc功能。因為其阻至內(nèi)存回收,所以可能會導(dǎo)致OutOfMemoryError錯誤,慎用。-Xincgc開啟增量gc(默認(rèn)為關(guān)閉)。這有助于減少長時間GC時應(yīng)用程序出現(xiàn)的停頓,但由于可能和應(yīng)用程序并發(fā)執(zhí)行,所以會降低CPU對應(yīng)用的處理能力。-Xloggc:file與-verbo:gc功能類似,只是將每次GC事件的相關(guān)情況記錄到一個文件中,文件的位置最好在本地,以避免網(wǎng)絡(luò)的潛在問題。6.3 不穩(wěn)定參數(shù)

            這是我們?nèi)粘i_發(fā)中接觸到最多的參數(shù)類型。這也是非標(biāo)準(zhǔn)化參數(shù),相對來說不穩(wěn)定,隨著JVM版本的變化可能會發(fā)生變化,主要用于JVM調(diào)優(yōu)和debug。

            不穩(wěn)定參數(shù)以-XX 開頭,此類參數(shù)的設(shè)置很容易引起JVM 性能上的差異,使JVM存在極大的不穩(wěn)定性。如果此類參數(shù)設(shè)置合理將大大提高JVM的性能及穩(wěn)定性。

            不穩(wěn)定參數(shù)分為三類:性能參數(shù):用于JVM的性能調(diào)優(yōu)和內(nèi)存分配控制,如內(nèi)存大小的設(shè)置行為參數(shù):用于改變JVM的基礎(chǔ)行為,如GC的方式和算法的選擇調(diào)試參數(shù):用于監(jiān)控、打印、輸出jvm的信息不穩(wěn)定參數(shù)語法規(guī)則:布爾類型參數(shù)值:-XX:+-XX:- 示例:-XX:+UG1GC,表示啟用G1垃圾收集器數(shù)字類型參數(shù)值: -XX: 示例:-XX:MaxGCPauMillis=500 ,表示設(shè)置GC的最大停頓時間是500ms字符串類型參數(shù)值: -XX: 示例:-XX:HeapDumpPath=./dump.core6.4 常參數(shù)

            –Xms4g -Xmx4g –Xmn1200m –Xss512k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 -XX:PermSize=100m -XX:MaxPermSize=256m -XX:MaxDirectMemorySize=1G -XX:+DisableExplicitGC

            參數(shù)解析:

            -Xms4g:初始化堆內(nèi)存大小為4GB,ms是memory start的簡稱,等價于-XX:InitialHeapSize。-Xmx4g:堆內(nèi)存最大值為4GB,mx是memory max的簡稱,等價于-XX:MaxHeapSize。-Xmn1200m:設(shè)置年輕代大小為1200MB。增大年輕代后,將會減小老年代大小。此值對系統(tǒng)性能影響較大, Sun官方推薦配置為整個堆的3/8 。-Xss512k:設(shè)置每個線程的堆棧大小。JDK5.0以后每個線程堆棧大小為1MB,以前每個線程堆棧大小為256K。應(yīng)根據(jù)應(yīng)用線程所需內(nèi)存大小進(jìn)行調(diào)整。在相同物理內(nèi)存下,減小這個值能生成更多的線程。但是操作系統(tǒng)對一個進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗值在3000~5000左右。-XX:NewRatio=4:設(shè)置年輕代(包括Eden和兩個Survivor區(qū))與老年代的比值(除去持久代)。設(shè)置為4,則年輕代與老年代所占比值為1:4,年輕代占整個堆棧的1/5-XX:SurvivorRatio=8:設(shè)置年輕代中Eden區(qū)與Survivor區(qū)的大小比值。設(shè)置為8,則兩個Survivor區(qū)與個Eden區(qū)的比值為2:8,個Survivor區(qū)占整個年輕代的1/10-XX:PermSize=100m:初始化永久代大小為100MB。-XX:MaxPermSize=256m:設(shè)置持久代大小為256MB。-XX:MaxTenuringThreshold=15:設(shè)置垃圾最大年齡。如果設(shè)置為0的話,則年輕代對象不經(jīng)過Survivor區(qū),直接進(jìn)入老年代。對于老年代比較多的應(yīng)用,可以提高效率。如果將此值設(shè)置為個較大值,則年輕代對象會在Survivor區(qū)進(jìn)行多次復(fù)制,這樣可以增加對象在年輕代的存活時間,增加在年輕代即被回收的概率。-XX:MaxDirectMemorySize=1G:直接內(nèi)存。報java.lang.OutOfMemoryError: Direct buffermemory異常可以上調(diào)這個值。-XX:+DisableExplicitGC:禁止運(yùn)行期顯式地調(diào)用System.gc()來觸發(fā)fulll GC。 注意: Java RMI的定時GC觸發(fā)機(jī)制可通過配置-Dsun.rmi.dgc.rver.gcInterval=86400來控制觸發(fā)的時間。-XX:CMSInitiatingOccupancyFraction=60:老年代內(nèi)存回收閾值,默認(rèn)值為68。-XX:ConcGCThreads=4:CMS垃圾回收器并行線程線,推薦值為CPU核心數(shù)。-XX:ParallelGCThreads=8:新生代并行收集器的線程數(shù)。-XX:CMSMaxAbortablePrecleanTime=500:當(dāng)abortable-preclean預(yù)清理階段執(zhí)行達(dá)到這個時間時就會結(jié)束。*新生代、老年代、永久代的參數(shù),如果不進(jìn)性指定,虛擬機(jī)會子動選擇合適的值,同時也會基于系統(tǒng)的開銷自動調(diào)整*。6.4.1 -XX:+PrintFlagsInitial、-XX:+PrintFlagsFinal

            Java 6(update 21oder 21之后)版本, HotSpot JVM 提供給了兩個新的參數(shù),在JVM啟動后,在命令行中可以輸出所有XX參數(shù)和值。 -XX:+PrintFlagsInitial:查看初始值 -XX:+PrintFlagsFinal:查看最終值(初始值可能被修改掉) 讓我們現(xiàn)在就了解一下新參數(shù)的輸出。以 -client 作為參數(shù)的 -XX:+ PrintFlagsFinal 的結(jié)果是一個按字母排序的590個參數(shù)表格(注意,每個relea版本參數(shù)的數(shù)量會不一樣)

            18.png

            表格的每一行包括五列,來表示一個XX參數(shù)。第一列表示參數(shù)的數(shù)據(jù)類型,第二列是名稱,第四列為值,第五列是參數(shù)的類別。第三列”=”表示第四列是參數(shù)的默認(rèn)值,而”:=” 表明了參數(shù)被用戶或者JVM賦值了。

            如果我們只想看下所有XX參數(shù)的默認(rèn)值,能夠用一個相關(guān)的參數(shù),-XX:+PrintFlagsInitial 。 用 -XX:+PrintFlagsInitial , 只是展示了第三列為“=”的數(shù)據(jù)(也包括那些被設(shè)置其他值的參數(shù))。

            然而,注意當(dāng)與-XX:+PrintFlagsFinal 對比的時候,一些參數(shù)會丟失,大概因為這些參數(shù)是動態(tài)創(chuàng)建的。

            19.png

            6.4.2 -XX:+PrintCommandLineFlags

            讓我們看下這個參數(shù),事實上這個參數(shù)非常有用: -XX:+PrintCommandLineFlags 。這個參數(shù)讓JVM打印出那些已經(jīng)被用戶或者JVM設(shè)置過的詳細(xì)的XX參數(shù)的名稱和值。

            換句話說,它列舉出 -XX:+PrintFlagsFinal的結(jié)果中第三列有":="的參數(shù)。以這種方式, 我們可以用-XX:+PrintCommandLineFlags作為快捷方式來查看修改過的參數(shù)。看下面的例子。

            20.png

            現(xiàn)在如果我們每次啟動java 程序的時候設(shè)置 -XX:+PrintCommandLineFlags 并且輸出到日志文件上,這樣會記錄下我們設(shè)置的JVM 參數(shù)對應(yīng)用程序性能的影響。

            6.4.3 GC日志相關(guān)

            設(shè)置JVM GC格式日志的主要參數(shù)包括如下8個:

            -XX:+PrintGC 輸出簡要GC日志-XX:+PrintGCDetails 輸出詳細(xì)GC日志-Xloggc:gc.log 輸出GC日志到文件-XX:+PrintGCTimeStamps 輸出GC的時間戳(以JVM啟動到當(dāng)期的總時長的時間戳形式)-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2020-04-26T21:53:59.234+0800)-XX:+PrintHeapAtGC 在進(jìn)行GC的前后打印出堆的信息-verbo:gc : 在JDK 8中,-verbo:gc是-XX:+PrintGC一個別稱,日志格式等價于:-XX:+PrintGC。不過在JDK 9中 -XX:+PrintGC被標(biāo)記為deprecated。 -verbo:gc是一個標(biāo)準(zhǔn)的選項,-XX:+PrintGC是一個實驗的選項,建議使用-verbo:gc 替代-XX:+PrintGC-XX:+PrintReferenceGC 打印年輕代各個引用的數(shù)量以及時長

            開啟GC日志多種方法都能開啟GC的日志功能,其中包括:使用-verbo:gc或-XX:+PrintGC這兩個標(biāo)志中的任意一個能創(chuàng)建基本的GC日志(這兩個日志標(biāo)志實際上互為別名,默認(rèn)情況下的GC日志功能是關(guān)閉的)使用-XX:+PrintGCDetails標(biāo)志會創(chuàng)建更詳細(xì)的GC日志。 推薦使用-XX:+PrintGCDetails標(biāo)志(這個標(biāo)志默認(rèn)情況下也是關(guān)閉的);通常情況下使用基本的GC日志很難診斷垃圾回收時發(fā)生的問題。

            開啟GC時間提示除了使用詳細(xì)的GC日志,我們還推薦使用-XX:+PrintGCTimeStamps或者-XX:+PrintGCDateStamps,便于我們更精確地判斷幾次GC操作之間的時間。這兩個參數(shù)之間的差別在于時間戳是相對于0(依據(jù)JVM啟動的時間)的值,而日期戳(date stamp)是實際的日期字符串。由于日期戳需要進(jìn)性格式化,所以它的效率可能會受輕微的影響,不過這種操作并不頻繁,它造成的影響也很難被我們感知。

            指定GC日志路徑默認(rèn)情況下GC日志直接輸出到標(biāo)準(zhǔn)輸出,不過使用-Xloggc:filename標(biāo)志也能修改輸出到某個文件。除了顯式地使用-PrintGCDetails標(biāo)志,否則使用-Xloggc會自動地開啟基本日志模式。

            使用日志循環(huán)(Log rotation)標(biāo)志可以限制保存在GC日志中的數(shù)據(jù)量;對于需要長時間運(yùn)行的服務(wù)器而言,這是一個非常有用的標(biāo)志,否則累積幾個月的數(shù)據(jù)很可能會耗盡服務(wù)器的磁盤。

            開啟日志滾動輸出通過-XX:+UGCLogfileRotation -XX:NumberOfGCLogfiles=N -XX:GCLogfileSize=N標(biāo)志可以控制日志文件的循環(huán)。 默認(rèn)情況下,UGCLogfileRotation標(biāo)志是關(guān)閉的。它負(fù)責(zé)打開或關(guān)閉GC日志滾動記錄功能的。要求必須設(shè)置 -Xloggc參數(shù)開啟UGCLogfileRotation標(biāo)志后,默認(rèn)的文件數(shù)目是0(意味著不作任何限制),默認(rèn)的日志文件大小是0(同樣也是不作任何限制)。因此,為了讓日志循環(huán)功能真正生效,我們必須為所有這些標(biāo)志設(shè)定值。

            需要注意的是:

            設(shè)置滾動日志文件的大小,必須大于8k。當(dāng)前寫日志文件大小超過該參數(shù)值時,日志將寫入下一個文件設(shè)置滾動日志文件的個數(shù),必須大于等于1必須設(shè)置 -Xloggc 參數(shù)開啟語句

            -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/hadoop/gc.log -XX:+UGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=512k

            其他有用參數(shù)-XX:+PrintGCApplicationStoppedTime 打印GC造成應(yīng)用暫停的時間 -XX:+PrintTenuringDistribution 在每次新生代 young GC時,輸出幸存區(qū)中對象的年齡分布

            日志含義

            21.png

            22.png

            6.4.4 -XX:CMSFullGCsBeforeCompaction

            CMSFullGCsBeforeCompaction 說的是,在上一次CMS并發(fā)GC執(zhí)行過后,到底還要再執(zhí)行多少次full GC才會做壓縮。默認(rèn)是0,也就是在默認(rèn)配置下每次CMS GC頂不住了而要轉(zhuǎn)入full GC的時候都會做壓縮。 如果把CMSFullGCsBeforeCompaction配置為10,就會讓上面說的第一個條件變成每隔10次真正的full GC才做一次壓縮(而不是每10次CMS并發(fā)GC就做一次壓縮,目前VM里沒有這樣的參數(shù))。這會使full GC更少做壓縮,也就更容易使CMS的old gen受碎片化問題的困擾。 本來這個參數(shù)就是用來配置降低full GC壓縮的頻率,以期減少某些full GC的暫停時間。CMS回退到full GC時用的算法是mark-sweep-compact,但compaction是可選的,不做的話碎片化會嚴(yán)重些但這次full GC的暫停時間會短些。這是個取舍。

            -XX:+UCMSCompactAtFullCollection-XX:CMSFullGCsBeforeCompaction=10

            兩個參數(shù)必須同時使用才能生效。

            6.4.5 -XX:HeapDumpPath

            堆內(nèi)存出現(xiàn)OOM的概率是所有內(nèi)存耗盡異常中最高的,出錯時的堆內(nèi)信息對解決問題非常有幫助,所以給JVM設(shè)置這個參數(shù)(-XX:+HeapDumpOnOutOfMemoryError),讓JVM遇到OOM異常時能輸出堆內(nèi)信息,并通過(-XX:+HeapDumpPath)參數(shù)設(shè)置堆內(nèi)存溢出快照輸出的文件地址,這對于特別是對相隔數(shù)月才出現(xiàn)的OOM異常來說尤為重要。 這兩個參數(shù)通常配套使用:

            -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./6.4.6 -XX:OnOutOfMemoryError

            -XX:OnOutOfMemoryError="/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/binjconsole"

            表示發(fā)生OOM后,運(yùn)行jconsole程序。這里可以不用加“”,因為jconsole.exe路徑Program Files含有空格。

            利用這個參數(shù),我們可以在系統(tǒng)OOM后,自定義一個腳本,可以用來發(fā)送郵件告警信息,可以用來重啟系統(tǒng)等等。

            6.4.7 XX:InitialCodeCacheSize

            JVM一個有趣的,但往往被忽視的內(nèi)存區(qū)域是“代碼緩存”,它是用來存儲已編譯方法生成的本地代碼。代碼緩存確實很少引起性能問題,但是一旦發(fā)生其影響可能是毀滅性的。如果代碼緩存被占滿,JVM會打印出一條警告消息,并切換到interpreted-only 模式:JIT編譯器被停用,字節(jié)碼將不再會被編譯成機(jī)器碼。因此,應(yīng)用程序?qū)⒗^續(xù)運(yùn)行,但運(yùn)行速度會降低一個數(shù)量級,直到有人注意到這個問題。

            就像其他內(nèi)存區(qū)域一樣,我們可以自定義代碼緩存的大小。相關(guān)的參數(shù)是-XX:InitialCodeCacheSize 和- XX:RervedCodeCacheSize,它們的參數(shù)和上面介紹的參數(shù)一樣,都是字節(jié)值。

            6.4.8 -XX:+UCodeCacheFlushing

            如果代碼緩存不斷增長,例如,因為熱部署引起的內(nèi)存泄漏,那么提高代碼的緩存大小只會延緩其發(fā)生溢出。

            為了避免這種情況的發(fā)生,我們可以嘗試一個有趣的新參數(shù):當(dāng)代碼緩存被填滿時讓JVM放棄一些編譯代碼。通過使用-XX:+UCodeCacheFlushing 這個參數(shù),我們至少可以避免當(dāng)代碼緩存被填滿的時候JVM切換到interpreted-only 模式。

            不過,我仍建議盡快解決代碼緩存問題發(fā)生的根本原因,如找出內(nèi)存泄漏并修復(fù)它。

            本文發(fā)布于:2023-02-28 20:02:00,感謝您對本站的認(rèn)可!

            本文鏈接:http://m.newhan.cn/zhishi/a/167765052676930.html

            版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時內(nèi)刪除。

            本文word下載地址:jdk1.5(jdk15.0.2是什么版本).doc

            本文 PDF 下載地址:jdk1.5(jdk15.0.2是什么版本).pdf

            標(biāo)簽:版本
            相關(guān)文章
            留言與評論(共有 0 條評論)
               
            驗證碼:
            推薦文章
            排行榜
            Copyright ?2019-2022 Comsenz Inc.Powered by ? 實用文體寫作網(wǎng)旗下知識大全大全欄目是一個全百科類寶庫! 優(yōu)秀范文|法律文書|專利查詢|
            主站蜘蛛池模板: 国产成人黄色自拍小视频| 91国产超碰在线观看| 丰满人妻被黑人猛烈进入| 十八禁午夜福利免费网站| A级日本乱理伦片免费入口| 五月天天天综合精品无码| 狠狠做五月深爱婷婷天天综合| 色图网免费视频在线观看十八禁 | 在线亚洲精品国产二区图片欧美| 日韩乱码人妻无码中文字幕| 99RE6在线视频精品免费下载| 最新精品国偷自产在线美女足| 亚洲国产精品成人综合色| 日本高清在线播放一区二区三区| 国产精品67人妻无码久久| 国产亚洲精品久久综合阿香| 国产一区二区精品偷系列| 亚洲蜜臀av乱码久久| 欧美精品亚洲精品日韩专 | 久久五月丁香激情综合| 人妻无码视频一区二区三区| 九色国产精品一区二区久久| 欧美人与动zozo在线播放| 亚洲AV日韩精品久久久久| 精品素人AV无码不卡在线观看| 清纯唯美人妻少妇第一页| 久久国内精品自在自线400部| 精品无码国产污污污免费| 国内精品免费久久久久电影院97| 午夜AAAAA级岛国福利在线 | 久久人人97超碰精品| 九九热精品免费在线视频| 亚洲精品国产一区二区三区在线观看| 丝袜a∨在线一区二区三区不卡| 亚洲中文字幕乱码一二三区| 久久这里只有精品少妇| 亚洲av乱码一区二区三区| 综合久久少妇中文字幕| 久久一级黄色大片免费观看| 亚洲AV成人片不卡无码| 性奴sm虐辱暴力视频网站 |