Chan Chen Coding...

          JVM參數(shù)設(shè)定

          在Linux或其他UNIX和類UNIX環(huán)境下,ps命令想必大家都不陌生,我相信也有不少同學(xué)寫過 ps aux | grep java | grep -v grep | awk '{print $2}' 這樣的管道命令來找出Java進(jìn)程的pid。常言道,Java并非真的"跨平臺",它自己就是平臺。作為平臺,當(dāng)然也有些基本的工具,讓我們可以用更簡單、更統(tǒng)一,同時又是非侵入的方式來查詢進(jìn)程相關(guān)信息。今天我們就來認(rèn)識一下其中的兩個。

          jps

          顧名思義,它對應(yīng)到UNIX的ps命令。用法如下:

          jps [ options ] [ hostid ]

          其中,options可以用 -q (安靜) -m (輸出傳遞給main方法的參數(shù)) -l (顯示完整路徑) -v (顯示傳遞給JVM的命令行參數(shù)) -V (顯示通過flag文件傳遞給JVM的參數(shù)) -J (和其他Java工具類似用于傳遞參數(shù)給命令本身要調(diào)用的java進(jìn)程);hostid是主機(jī)id,默認(rèn)localhost。

          jstat

          用于輸出給定java進(jìn)程的統(tǒng)計信息。用法如下:

          jstat -options 可以列出當(dāng)前JVM版本支持的選項,常見的有 -class (類加載器) -compiler (JIT) -gc (GC堆狀態(tài)) -gccapacity (各區(qū)大小) -gccause (最近一次GC統(tǒng)計和原因) -gcnew (新區(qū)統(tǒng)計) -gcnewcapacity (新區(qū)大小) -gcold (老區(qū)統(tǒng)計) -gcoldcapacity (老區(qū)大小) -gcpermcapacity (永久區(qū)大小) -gcutil (GC統(tǒng)計匯總) -printcompilation (HotSpot編譯統(tǒng)計)

          假定你要監(jiān)控的Java進(jìn)程號是12345,那么
          jstat -gcutil -t 12345 200 300 即可每200毫秒連續(xù)打印300次帶有時間戳的GC統(tǒng)計信息。

          簡單解釋一下: -gcutil是傳入的option;必選,-t是打印時間戳,是以目標(biāo)JVM啟動時間為起點計算的,可選;12345是vmid/pid,和我們從jps拿到的是一樣的,必選;200是監(jiān)控時間間隔,可選,不提供就意味著單次輸出;300是最大輸出次數(shù),可選,不提供且監(jiān)控時間間隔有值的話,就是無限期打印下去。



          jstat

                 1. jstat -gc pid

                      可以顯示gc的信息,查看gc的次數(shù),及時間。

                      其中最后五項,分別是young gc的次數(shù),young gc的時間,full gc的次數(shù),full gc的時間,gc的總時間。

                2.jstat -gccapacity pid

                      可以顯示,VM內(nèi)存中三代(young,old,perm)對象的使用和占用大小,

                      如:PGCMN顯示的是最小perm的內(nèi)存使用量,PGCMX顯示的是perm的內(nèi)存最大使用量,

                      PGC是當(dāng)前新生成的perm內(nèi)存占用量,PC是但前perm內(nèi)存占用量。

                      其他的可以根據(jù)這個類推, OC是old內(nèi)純的占用量。

               3.jstat -gcutil pid

                      統(tǒng)計gc信息統(tǒng)計。

               4.jstat -gcnew pid

                     年輕代對象的信息。

               5.jstat -gcnewcapacity pid

                     年輕代對象的信息及其占用量。

               6.jstat -gcold pid

                    old代對象的信息。

               7.stat -gcoldcapacity pid

                    old代對象的信息及其占用量。

               8.jstat -gcpermcapacity pid

                    perm對象的信息及其占用量。

               9.jstat -class pid

                    顯示加載class的數(shù)量,及所占空間等信息。
               10.jstat -compiler pid

                    顯示VM實時編譯的數(shù)量等信息。

               11.stat -printcompilation pid

                    當(dāng)前VM執(zhí)行的信息。

                  一些術(shù)語的中文解釋:

                   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é))
                     PC:Perm(持久代)的容量 (字節(jié))
                     PU:Perm(持久代)目前已使用空間 (字節(jié))
                   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)

              NGCMN:年輕代(young)中初始化(最小)的大小 (字節(jié))

              NGCMX:年輕代(young)的最大容量 (字節(jié))

                  NGC:年輕代(young)中當(dāng)前的容量 (字節(jié))

             OGCMN:old代中初始化(最小)的大小 (字節(jié)) 

             OGCMX:old代的最大容量 (字節(jié))

                 OGC:old代當(dāng)前新生成的容量 (字節(jié))

             PGCMN:perm代中初始化(最小)的大小 (字節(jié)) 

             PGCMX:perm代的最大容量 (字節(jié))   

                 PGC:perm代當(dāng)前新生成的容量 (字節(jié))

                    S0:年輕代中第一個survivor(幸存區(qū))已使用的占當(dāng)前容量百分比

                   S1:年輕代中第二個survivor(幸存區(qū))已使用的占當(dāng)前容量百分比

                     E:年輕代中Eden(伊甸園)已使用的占當(dāng)前容量百分比

                     O:old代已使用的占當(dāng)前容量百分比

                     P:perm代已使用的占當(dāng)前容量百分比

            S0CMX:年輕代中第一個survivor(幸存區(qū))的最大容量 (字節(jié))

           S1CMX :年輕代中第二個survivor(幸存區(qū))的最大容量 (字節(jié))

              ECMX:年輕代中Eden(伊甸園)的最大容量 (字節(jié))

                 DSS:當(dāng)前需要survivor(幸存區(qū))的容量 (字節(jié))(Eden區(qū)已滿)

                    TT: 持有次數(shù)限制

                 MTT : 最大持有次數(shù)限制








          虛擬機(jī)中的共劃分為三個代:年輕代(Young Generation)、年老點(Old Generation)和持久代(Permanent Generation)。其中持久代主要存放的是Java類的類信息,與垃圾收集要收集的Java對象關(guān)系不大。年輕代和年老代的劃分是對垃圾收集影響比較大的。

            年輕代:

            所有新生成的對象首先都是放在年輕代的。年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對象。年輕代分三個區(qū)。一個Eden區(qū),兩個 Survivor區(qū)(一般而言)。大部分對象在Eden區(qū)中生成。當(dāng)Eden區(qū)滿時,還存活的對象將被復(fù)制到Survivor區(qū)(兩個中的一個),當(dāng)這個 Survivor區(qū)滿時,此區(qū)的存活對象將被復(fù)制到另外一個Survivor區(qū),當(dāng)這個Survivor去也滿了的時候,從第一個Survivor區(qū)復(fù)制過來的并且此時還存活的對象,將被復(fù)制“年老區(qū)(Tenured)”。需要注意,Survivor的兩個區(qū)是對稱的,沒先后關(guān)系,所以同一個區(qū)中可能同時存在從Eden復(fù)制過來對象,和從前一個Survivor復(fù)制過來的對象,而復(fù)制到年老區(qū)的只有從第一個Survivor去過來的對象。而且,Survivor區(qū)總有一個是空的。同時,根據(jù)程序需要,Survivor區(qū)是可以配置為多個的(多于兩個),這樣可以增加對象在年輕代中的存在時間,減少被放到年老代的可能。

            年老代:

            在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對象,就會被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長的對象。

            持久代:

            用于存放靜態(tài)文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應(yīng)用可能動態(tài)生成或者調(diào)用一些class,例如Hibernate 等,在這種時候需要設(shè)置一個比較大的持久代空間來存放這些運行過程中新增的類。持久代大小通過-XX:MaxPermSize=<N>進(jìn)行設(shè)置。



          什么情況下觸發(fā)垃圾回收:

              由于對象進(jìn)行了分代處理,因此垃圾回收區(qū)域、時間也不一樣。GC有兩種類型:Scavenge GC和Full GC。

              Scavenge GC

              一般情況下,當(dāng)新對象生成,并且在Eden申請空間失敗時,就會觸發(fā)Scavenge GC,對Eden區(qū)域進(jìn)行GC,清除非存活對象,并且把尚且存活的對象移動到Survivor區(qū)。然后整理Survivor的兩個區(qū)。這種方式的GC是對年輕代的Eden區(qū)進(jìn)行,不會影響到年老代。因為大部分對象都是從Eden區(qū)開始的,同時Eden區(qū)不會分配的很大,所以Eden區(qū)的GC會頻繁進(jìn)行。因而,一般在這里需要使用速度快、效率高的算法,使Eden去能盡快空閑出來。

              Full GC

              對整個堆進(jìn)行整理,包括Young、Tenured和Perm。Full GC因為需要對整個對進(jìn)行回收,所以比Scavenge GC要慢,因此應(yīng)該盡可能減少Full GC的次數(shù)。在對JVM調(diào)優(yōu)的過程中,很大一部分工作就是對于FullGC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:

          -server -Xmx3000m -Xms3000m -Xmn1200m -Xss256k -XX:SurvivorRatio=8 -XX:PermSize=96m -XX:MaxPermSize=96m -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection  
          -XX:+CMSClassUnloadingEnabled  -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/app_admin/logs/oom.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps  -Xloggc:/home/app_admin/logs/gc.log
          -Xmx3000m設(shè)置JVM最大可用內(nèi)存為3000M。

           

          -Xms3000m設(shè)置JVM促使內(nèi)存為3000M。可設(shè)置與-Xmx相同,避免每次gc后JVM重新分配內(nèi)存。

          -Xmn1200m設(shè)置年輕代大小為1200m。整個堆大小=年輕代大小+年老代大小。增大年輕代后,將會減小年老代大小。此值對系統(tǒng)性能影響較大,Sun官方推薦配置為整個堆的3/8。

          -Xss256k 設(shè)置每個線程的堆棧大小。JDK5.0以后每個線程堆棧大小為1024k,以前每個線程堆棧大小為256K。根據(jù)應(yīng)用的線程所需內(nèi)存大小進(jìn)行調(diào)整。在相同物理內(nèi)存下,減小這個值能生成更多的線程。但是操作系統(tǒng)對一個進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗值在3000~5000左右。

          -XX:PermSize=96m  -XX:MaxPermSize=96m:設(shè)置持久代大小為64m,根據(jù)應(yīng)用自身class文件大小進(jìn)行設(shè)置,運行時空余量在10%------20%左右。

          -XX:+UseConcMarkSweepGC設(shè)置年老代為并發(fā)收集。

          -XX:+UseParNewGC:設(shè)置年輕代為并行收集。可與CMS收集同時使用。JDK5.0以上,JVM會根據(jù)系統(tǒng)配置自行設(shè)置,所以無需再設(shè)置此值。

          -XX:-CMSParallelRemarkEnabled :If the -XX:+UseParNewGC option is in use the remark pauses may be decreased with the -XX:+CMSParallelRemarkEnabled option.

          -XX:+UseCMSCompactAtFullCollection打開對年老代的壓縮。可能會影響性能,但是可以消除碎片(-XX:CMSFullGCsBeforeCompaction=5:由于并發(fā)收集器不對內(nèi)存空間進(jìn)行壓縮、整理,所以運行一段時間以后會產(chǎn)生"碎片",使得運行效率降低。此值設(shè)置運行多少次GC以后對內(nèi)存空間進(jìn)行壓縮、整理, 避免每次壓縮性能消耗)

          *-XX:+CMSClassUnloadingEnabled:*Perm Gen的使用到達(dá)一定的比率(默認(rèn)為92% ) 出發(fā)cms回收

          -XX:+DisableExplicitGC:屏蔽system.gc(), 這種顯示調(diào)用垃圾回收

          -XX:+HeapDumpOnOutOfMemoryError:內(nèi)存溢出打印堆棧信息

          -XX:HeapDumpPath=/home/app_admin/logs/oom.log:heapdump的日志文件路徑

          -XX:+PrintGCDetails:打印gc日志詳情

          -XX:+PrintGCDateStamps:打印gc時的具體時間

          -Xloggc:/home/app_admin/logs/gc.log:gc打印日志文件的路徑

          JVM內(nèi)存結(jié)構(gòu)

          •      Method Area------方法區(qū),被Class Loader所裝載的class文件以及相關(guān)的方法信息、域信息、靜態(tài)變量等都存放在這個區(qū)域內(nèi)。該區(qū)域是所有Java線程所共享的。(設(shè)置方法區(qū)內(nèi)存大小:-XX:PermSize -XX:MaxPermSize)

          •      Heap------堆區(qū),這個區(qū)域就是用來存放java對象的,通常GC也是針對該區(qū)域。一個Java虛擬機(jī)實例只有一個堆,并直接由java虛擬機(jī)進(jìn)行管理,在虛擬機(jī)啟動時創(chuàng)建。該區(qū)域可以被所有Java線程所共享。(設(shè)置堆內(nèi)存大小:-Xms  -Xmx -Xmn)

          •      Stack------棧區(qū),用來存放JVM的內(nèi)存局部變量和操作數(shù)棧。通常虛擬機(jī)對它的操作比較簡單(以幀為單位的壓棧和出棧),速度也很快。每個線程都有自己的棧,且棧可以不連續(xù)。(設(shè)置棧內(nèi)存大小:-Xss)

          •      Program Counter Register------每一個線程都有自己的一個PC寄存器,用于存放下一條被執(zhí)行的指令的地址。每個線程的PC寄存器在線程啟動時產(chǎn)生。

          •      Native Method Stack------保存本地方法進(jìn)入?yún)^(qū)域的地址。(設(shè)置棧內(nèi)存大小:-Xss)
            






          GC日志格式說明:

          [GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]

          <collector>GC收集器的名稱

          <starting occupancy1> 新生代在GC前占用的內(nèi)存

          <ending occupancy1> 新生代在GC后占用的內(nèi)存

          <pause time1> 新生代局部收集時jvm暫停處理的時間

          <starting occupancy3> JVM Heap 在GC前占用的內(nèi)存

          <ending occupancy3> JVM Heap 在GC后占用的內(nèi)存

          <pause time3> GC過程中jvm暫停處理的總時間

          YGC收集信息

          2012-2-7T19:24:29.040+0800: 10429.503: [GC [PSYoungGen: 484520K->2577K(495936K)] 734774K->254308K(3129664K), 0.0118730 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]

          FGC收集信息

          2012-2-7T19:38:37.391+0800: 10804.897: [Full GC (System) [PSYoungGen: 684K->0K(468416K)] [PSOldGen: 342164K->257451K(1060864K)] 342849K->257451K(1529280K) [PSPermGen: 123775K->122206K(237248K)], 1.1808050 secs] [Times: user=0.99 sys=0.18, real=1.18 secs] 

          JVM運行期分析工具

          jps 虛擬機(jī)進(jìn)程狀況工具

          jinfo java配置信息工具

          jstat 虛擬機(jī)統(tǒng)計信息監(jiān)視工具

          jmap java內(nèi)存映射工具

          jhat 虛擬機(jī)堆轉(zhuǎn)儲快照分析工具

          jstack java堆棧跟蹤工具 



          -----------------------------------------------------
          Silence, the way to avoid many problems;
          Smile, the way to solve many problems;

          posted on 2013-05-09 18:17 Chan Chen 閱讀(279) 評論(0)  編輯  收藏 所屬分類: Scala / Java

          主站蜘蛛池模板: 江城| 宿州市| 永胜县| 通州市| 登封市| 凌云县| 万山特区| 娱乐| 赫章县| 贵溪市| 日照市| 太湖县| 镇康县| 东宁县| 桓仁| 九江县| 故城县| 景德镇市| 敦煌市| 郯城县| 宜阳县| 井研县| 昂仁县| 卓资县| 建平县| 桂阳县| 秭归县| 梁山县| 南雄市| 花垣县| 蕲春县| 宁阳县| 惠安县| 福鼎市| 赞皇县| 聂拉木县| 保靖县| 达拉特旗| 阜康市| 阳谷县| 水富县|