程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻java內存檢查與剖析詳解

深刻java內存檢查與剖析詳解

編輯:關於JAVA

深刻java內存檢查與剖析詳解。本站提示廣大學習愛好者:(深刻java內存檢查與剖析詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻java內存檢查與剖析詳解正文


1:gc日記輸入
在jvm啟動參數中參加 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime,jvm將會依照這些參數次序輸入gc概要信息,具體信息,gc時光信息,gc形成的運用暫停時光。假如在適才的參數前面參加參數 -Xloggc:文件途徑,gc信息將會輸入到指定的文件中。其他參數還有
-verbose:gc和-XX:+PrintTenuringDistribution等。
2:jconsole
jconsole是jdk自帶的一個內存剖析對象,它供給了圖形界面。可以檢查到被監控的jvm的內存信息,線程信息,類加載信息,MBean信息。
jconsole位於jdk目次下的bin目次,在windows下是jconsole.exe,在unix和linux下是jconsole.sh,jconsole可以監控當地運用,也能夠監控長途運用。 要監控當地運用,履行jconsole pid,pid就是運轉的java過程id,假如不帶上pid參數,則履行jconsole敕令後,會看到一個對話框彈出,下面列出了當地的java過程,可以選擇一個停止監控。假如要長途監控,則要在長途辦事器的jvm參數裡參加一些器械,由於jconsole的長途監控基於jmx的,關於jconsole具體用法,請見專門引見jconsle的文章,我也會在博客裡專門具體引見jconsole。
3:jviusalvm
在JDK6 update 7以後,jdk推出了別的一個對象:jvisualvm,java可視化虛擬機,它不只供給了jconsole相似的功效,還供給了jvm內存和cpu及時診斷,還有手動dump出jvm內存情形,手動履行gc。
和jconsole一樣,運轉jviusalvm,在jdk的bin目次下履行jviusalvm,windows下是jviusalvm.exe,linux和unix下是jviusalvm.sh。
4:jmap
jmap是jdk自帶的jvm內存剖析的對象,位於jdk的bin目次。jdk1.6中jmap敕令用法:

Usage:
jmap -histo <pid>
(to connect to running process and print histogram of java object heap
jmap -dump:<dump-options> <pid>
(to connect to running process and dump java heap)
dump-options:
format=b binary default
file=<file>  dump heap to <file>
Example:   jmap -dump:format=b,file=heap.bin <pid>
jmap -histo <pid>在屏幕上顯示出指定pid的jvm內存狀態。以我本機為例,履行該敕令,屏幕顯示:
num #instances #bytes  class name
----------------------------------------------
1: 242062791864  <constMethodKlass>
2: 223712145216  [C
3: 242061940648  <methodKlass>
4:  19511364496  <constantPoolKlass>
5: 265431282560  <symbolKlass>
6:  63771081744  [B
7:  1793 909688  <constantPoolCacheKlass>
8:  1471 614624  <instanceKlassKlass>
9: 14581 548336  [Ljava.lang.Object;
10:  3863 513640  [I
11: 20677 496248  java.lang.String
12:  3621 312776  [Ljava.util.HashMap$Entry;
13:  3335 266800  java.lang.reflect.Method
14:  8256 264192  java.io.ObjectStreamClass$WeakClassKey
15:  7066 226112  java.util.TreeMap$Entry
16:  2355 173304  [S
17:  1687 161952  java.lang.Class
18:  2769 150112  [[I
19:  3563 142520  java.util.HashMap
20:  5562 133488  java.util.HashMap$Entry
Total239019   17140408

為了便利檢查,我刪失落了一些行。從下面的信息很輕易看出,#instance指的是對象數目,#bytes指的是這些對象占用的內存年夜小,class name指的是對象類型。
再看jmap的dump選項,這個選項是將jvm的堆中內存信息輸入到一個文件中,在我本機履行
jmap -dump:file=c:dump.txt 340
留意340是我本機的java過程pid,dump出來的文件比擬年夜有10幾M,並且我只是開了tomcat,跑了一個很簡略的運用,且沒有任何拜訪,可以想象,年夜型忙碌的辦事器上,dump出來的文件該有多年夜。須要曉得的是,dump出來的文件信息是很原始的,毫不合適人直接不雅看,而jmap -histo顯示的內容又太簡略,例如只顯示某些類型的對象占用多年夜內存,和這些對象的數目,然則沒有更具體的信息,例如這些對象分離是由誰創立的。那這麼說,dump出來的文件有甚麼用呢?固然有效,由於有專門剖析jvm的內存dump文件的對象。
5:jhat
下面說了,有許多對象都能剖析jvm的內存dump文件,jhat就是sun jdk6及以上版本自帶的對象,位於jdk的bin目次,履行 jhat -J -Xmx512m [file] ,file就是dump文件途徑。jhat內置一個簡略的web辦事器,此敕令履行後,jhat在敕令行裡顯示剖析成果的拜訪地址,可以用-port選項指定端口,詳細用法可以履行jhat -heap檢查贊助信息。拜訪指定地址後,就可以看到頁面上顯示的信息,比jmap -histo敕令顯示的豐碩很多,更加具體。
6:eclipse內存剖析器
下面說了jhat,它能剖析jvm的dump文件,然則全體是文字顯示,eclipse memory analyzer,是一個eclipse供給用於剖析jvm 堆dump的插件,它的剖析速度比jhat快,剖析成果是圖形界面顯示,比jhat的可讀性更高。其實jvisualvm也能夠剖析dump文件,也是有圖形界面顯示的。
7:jstat
假如說jmap偏向於剖析jvm內存中對象信息的話,那末jsta就是偏向於剖析jvm內存的gc情形。都是jvm內存剖析對象,但明顯,它們是從分歧維度來剖析的。jsat經常使用的參數有許多,如 -gc,-gcutil,-gccause,這些選項詳細感化可檢查jsat贊助信息,我常常用-gcutil,這個參數的感化赓續的顯示以後指定的jvm內存的渣滓搜集的信息。
我在本機履行 jstat -gcutil 340 10000,這個敕令是每一個10秒鐘輸入一次jvm的gc信息,10000指的是距離時光為10000毫秒。屏幕上顯示以下信息(我只取了第一行,由於是按的必定頻率顯示,所以現實履行的時刻,會有許多行):

S0 S1 E  O  P YGC YGCTFGCFGCT GCT
54.62   0.00  42.87  43.52  86.24   17925.093337.670   12.763

額……怎樣說呢,要看懂這些信息代表甚麼意思,還必需對jvm的gc機制有必定的懂得才行啊。其實假如對sun的 hot spot jvm的gc比擬懂得的人,應當很輕易看懂這些信息,然則不清晰gc機制的人,有點莫明其妙,所以在這裡我照樣先講講sun的jvm的gc機制吧。說到gc,其實不只僅只是java的概念,其其實java之前,就有許多說話有gc的概念了,gc嘛就是渣滓搜集的意思,更多的是一種算法性的器械,而跟詳細說話沒太年夜關系,所以關於gc的汗青,gc的主流算法我就不講了,那扯得太遠了,扯得太遠了就是扯淡。sun如今的jvm,內存的治理模子是分代模子,所以gc固然是分代搜集了。分代是甚麼意思呢?就是將對象依照性命周期分紅三個條理,分離是:重生代,舊生代,耐久代。對象剛開端分派的時刻,年夜部門都在重生代,當重生代gc提交被觸發後了,履行一次重生代規模內的gc,這叫minor gc,假如履行了幾回minor gc後,還有對象存活,將這些對象轉入舊生代,由於這些對象曾經經由了組織的重重考驗了哇。舊生代的gc頻率會更低一些,假如舊生代履行了gc,那就是full gc,由於不是部分gc,而是全內存規模的gc,這會形成運用停留,由於全內存搜集,必需封閉內存,不准有新的對象分派到內存,耐久代就是一些jvm時代,根本不會消逝的對象,例如class的界說,jvm辦法區信息,例如靜態塊。須要重要的是,重生代裡又分了三個空間:eden,susvivor0,susvivor1,按字面下去懂得,就是伊甸園區,幸存1區,幸存2區。新對象分派在eden區中,eden區滿時,采取標志-復制算法,即檢討出eden區存活 的對象,並將這些對象復制到是s0或s1中,然後清空eden區。jvm的gc說開來,不只是這麼簡略,例如還有串行搜集,並行搜集,並發搜集,還有知名的火車算法,不外那說得太遠了,如今對這個有年夜致懂得就好。說到這裡,再來看一下下面輸入的信息:

S0   S1   EO  P   YGC YGCTFGCFGCT GCT
54.62   0.00  42.87  43.52  86.24   17925.093337.670   12.763
S0:重生代的susvivor0區,空間應用率為5462%
S1:重生代的susvivor1區,空間應用率為0.00%(由於還沒有履行第二次minor搜集)
E:eden區,空間應用率42.87%
O:舊生代,空間應用率43.52%
P:耐久帶,空間應用率86.24%
YGC:minor gc履行次數1792次
YGCT:minor gc消耗的時光5.093毫秒
FGC:full gc履行次數33
FGCT:full gc消耗的時光7.670毫秒
GCT:gc消耗的總時光12.763毫秒

如何選擇對象
下面羅列的一些對象,各有益弊,其實假如在開辟情況,應用甚麼樣的對象是無所謂的,只需能獲得成果就好。然則在臨盆情況裡,卻不克不及亂選擇,由於這些對象自己就會消耗年夜量的體系資本,假如在一個臨盆辦事器壓力很年夜的時刻,冒然履行這些對象,能夠會形成很不測的情形。最好不要在辦事器本機監控,長途監控會比擬好一些,然則假如要長途監控,辦事器真個啟動劇本要參加一些jvm參數,例如用jconsloe長途監控tomcat或jboss等,都須要設置jvm的jmx參數,假如僅僅只是剖析辦事器的內存分派和gc信息,激烈推舉,先用jmap導出辦事器真個jvm的堆dump文件,然後再用jhat,或許jvisualvm,或許eclipse內存剖析器來剖析內存狀態。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved