java堆查看
『壹』 查看java對象占堆內存多少個位元組
object
o=new
object():
在java中空對象佔八個位元組,對象的引用佔四個位元組。所以上面那條語句所佔的空間是4byte+8byte=12byte.java中的內存是以8的倍數來分配的,所以分配的內存是16byte.
舉個例子:
class
o{
int
i;
byte
j;
string
s;
}
其所佔內存的大小是空對象(8)+int(4)+byte(1)+string引用(4)=17byte,因要是8的整數倍,所以其佔大小為24byte.
當然,如果類里有其他對象的話,也要把其他對象的空間算進去。
『貳』 如何查看GC 及jvm配置
java雖然是自動回收內存,但是應用程序,尤其伺服器程序最好根據業務情況指明內存分配限制。否則可能導致應用程序宕掉。
舉例說明含義:
-Xms128m
表示JVM Heap(堆內存)最小尺寸128MB,初始分配
-Xmx512m
表示JVM Heap(堆內存)最大允許的尺寸256MB,按需分配。
說明:如果-Xmx不指定或者指定偏小,應用可能會導致java.lang.OutOfMemory錯誤,此錯誤來自JVM不是Throwable的,無法用try...catch捕捉。
PermSize和MaxPermSize指明虛擬機為java永久生成對象(Permanate generation)如,class對象、方法對象這些可反射(reflective)對象分配內存限制,這些內存不包括在Heap(堆內存)區之中。
-XX:PermSize=64MB 最小尺寸,初始分配
-XX:MaxPermSize=256MB 最大允許分配尺寸,按需分配
過小會導致:java.lang.OutOfMemoryError: PermGen space
MaxPermSize預設值和-server -client選項相關。
-server選項下默認MaxPermSize為64m
-client選項下默認MaxPermSize為32m
經驗:
1、慎用最小限制選項Xms,PermSize已節約系統資源。
=========================================================
近期研究對jvm的內存使用情況進行監控,因此對觀察虛擬機的內存使用方法做了一些收集,對jvm的參數設置了解了一下:
幾個基本概念:
PermGen space:全稱是Permanent Generation space,即永久代。就是說是永久保存的區域,用於存放Class和Meta信息,Class在被Load的時候被放入該區域,GC(Garbage Collection)應該不會對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。
Heap space:存放Instance。Java Heap分為3個區,Young即新生代,Old即老生代和Permanent。Young保存剛實例化的對象。當該區被填滿時,GC會將對象移到Old區。Permanent區則負責保存反射對象。
幾個參數設置的意義:
xms/xmx:定義YOUNG+OLD段的總尺寸,ms為JVM啟動時YOUNG+OLD的內存大小;mx為最大可佔用的YOUNG+OLD內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
NewSize/MaxNewSize:定義YOUNG段的尺寸,NewSize為JVM啟動時YOUNG的內存大小;MaxNewSize為最大可佔用的YOUNG內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
PermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的內存大小;MaxPermSize為最大可佔用的Perm內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
SurvivorRatio:設置YOUNG代中Survivor空間和Eden空間的比例
申請一塊內存的過程:
A. JVM會試圖為相關Java對象在Eden中初始化一塊內存區域
B. 當Eden空間足夠時,內存申請結束。否則到下一步
C. JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收);釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區/OLD區
D. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區
E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)
F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現」out of memory錯誤」
我們的一種resin伺服器的jvm參數設置:
「-Xmx2000M -Xms2000M -Xmn500M -XX:PermSize=250M -XX:MaxPermSize=250M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:=60 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log」
是一種典型的響應時間優先型的配置。
Java中有四種不同的回收演算法,對應的啟動參數為
–XX:+UseSerialGC
–XX:+UseParallelGC
–XX:+UseParallelOldGC
–XX:+UseConcMarkSweepGC
1. Serial Collector
大部分平台或者強制 java -client 默認會使用這種。
young generation演算法 = serial
old generation演算法 = serial (mark-sweep-compact)
這種方法的缺點很明顯,stop-the-world, 速度慢。伺服器應用不推薦使用。
2. Parallel Collector
在linux x64上默認是這種,其他平台要加 java -server 參數才會默認選用這種。
young = parallel,多個thread同時
old = mark-sweep-compact = 1
優點:新生代回收更快。因為系統大部分時間做的gc都是新生代的,這樣提高了throughput(cpu用於非gc時間)
缺點:當運行在8G/16G server上old generation live object太多時候pause time過長
3. Parallel Compact Collector (ParallelOld)
young = parallel = 2
old = parallel,分成多個獨立的單元,如果單元中live object少則回收,多則跳過
優點:old old generation上性能較 parallel 方式有提高
缺點:大部分server系統old generation內存佔用會達到60%-80%, 沒有那麼多理想的單元live object很少方便迅速回收,同時compact方面開銷比起parallel並沒明顯減少。
4. Concurent Mark-Sweep(CMS) Collector
young generation = parallel collector = 2
old = cms
同時不做 compact 操作。
優點:pause time會降低, pause敏感但CPU有空閑的場景需要建議使用策略4.
缺點:cpu佔用過多,cpu密集型伺服器不適合。另外碎片太多,每個object的存儲都要通過鏈表連續跳n個地方,空間浪費問題也會增大。
內存監控的方法:
1. jmap -heap pid
查看java 堆(heap)使用情況
using thread-local object allocation.
Parallel GC with 4 thread(s) //GC 方式
Heap Configuration: //堆內存初始化配置
MinHeapFreeRatio=40 //對應jvm啟動參數-XX:MinHeapFreeRatio設置JVM堆最小空閑比率(default 40)
MaxHeapFreeRatio=70 //對應jvm啟動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閑比率(default 70)
MaxHeapSize=512.0MB //對應jvm啟動參數-XX:MaxHeapSize=設置JVM堆的最大大小
NewSize = 1.0MB //對應jvm啟動參數-XX:NewSize=設置JVM堆的『新生代』的默認大小
MaxNewSize =4095MB //對應jvm啟動參數-XX:MaxNewSize=設置JVM堆的『新生代』的最大大小
OldSize = 4.0MB //對應jvm啟動參數-XX:OldSize=<value>:設置JVM堆的『老生代』的大小
NewRatio = 8 //對應jvm啟動參數-XX:NewRatio=:『新生代』和『老生代』的大小比率
SurvivorRatio = 8 //對應jvm啟動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值
PermSize= 16.0MB //對應jvm啟動參數-XX:PermSize=<value>:設置JVM堆的『永生代』的初始大小
MaxPermSize=64.0MB //對應jvm啟動參數-XX:MaxPermSize=<value>:設置JVM堆的『永生代』的最大大小
Heap Usage: //堆內存分步
PS Young Generation
Eden Space: //Eden區內存分布
capacity = 20381696 (19.4375MB) //Eden區總容量
used = 20370032 (19.426376342773438MB) //Eden區已使用
free = 11664 (0.0111236572265625MB) //Eden區剩餘容量
99.94277218147106% used //Eden區使用比率
From Space: //其中一個Survivor區的內存分布
capacity = 8519680 (8.125MB)
used = 32768 (0.03125MB)
free = 8486912 (8.09375MB)
0.38461538461538464% used
To Space: //另一個Survivor區的內存分布
capacity = 9306112 (8.875MB)
used = 0 (0.0MB)
free = 9306112 (8.875MB)
0.0% used
PS Old Generation //當前的Old區內存分布
capacity = 366280704 (349.3125MB)
used = 322179848 (307.25464630126953MB)
free = 44100856 (42.05785369873047MB)
87.95982001825573% used
PS Perm Generation //當前的 「永生代」 內存分布
capacity = 32243712 (30.75MB)
used = 28918584 (27.57891082763672MB)
free = 3325128 (3.1710891723632812MB)
89.68751488662348% used
=====================================================================
jps
-q只輸出進程ID,而不輸出類的短名稱
-m用於輸出傳遞給Java進程(主函數)的參數
-l完整路徑
-v顯示傳遞給jvm的參數
『叄』 如何查看java虛擬機堆內存的參數值
請確保java_home/bin配置到path環境變數下,因為這些工具都在jdk的bin目錄下
jps(JVM Process Status Tool):JVM機進程狀況工具
用來查看基於HotSpot JVM裡面所有進程的具體狀態, 包括進程ID,進程啟動的路徑等等。與unix上的ps類似,用來顯示本地有許可權的java進程,可以查看本地運行著幾個java程序,並顯示他們的進程號。使用jps時,不需要傳遞進程號做為參數。
Jps也可以顯示遠程系統上的JAVA進程,這需要遠程服務上開啟了jstat服務,以及RMI注及服務,不過常用都是對本對的JAVA進程的查看。
命令格式:jps [ options ] [ hostid ]
常用參數說明:
-m 輸出傳遞給main方法的參數,如果是內嵌的JVM則輸出為null。
-l 輸出應用程序主類的完整包名,或者是應用程序JAR文件的完整路徑。
-v 輸出傳給JVM的參數。
例如:
C:\Users\Administrator>jps -lmv
1796 -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m -XX:MaxPermSize=256m
7340 sun.tools.jps.Jps -lmv -Denv.class.path=.;D:\DevTools\VM\jdk1.6.0_31\\lib\dt.jar;D:\DevTools\VM\jdk1.6.0_31\\lib\tools.jar; -Dapplication.home=D:\DevTools\VM\jdk1.6.0_31 -Xms8m
其中pid為1796的是我的eclipse進程,pid為7340的是jps命令本身的進程
jinfo(Configuration Info for Java):JVM配置信息工具
可以輸出並修改運行時的java 進程的opts。用處比較簡單,用於輸出JAVA系統參數及命令行參數
命令格式:jinfo [ options ] [ pid ]
常用參數說明:
-flag 輸出,修改,JVM命令行參數
例如:
C:\Users\Administrator>jinfo 1796
將會列印出很多jvm運行時參數信息,由於比較長這里不再列印出來,可以自己試試,內容一目瞭然
Jstack(Stack Trace for Java):JVM堆棧跟蹤工具
jstack用於列印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息,如果是在64位機器上,需要指定選項"-J-d64「
命令格式:jstack [ option ] pid
常用參數說明:
-F 當』jstack [-l] pid』沒有相應的時候強制列印棧信息
-l 長列表. 列印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表.
-m 列印java和native c/c++框架的所有棧信息.
-h | -help列印幫助信息
例如:
C:\Users\Administrator>jstack 1796
2013-05-22 11:42:38
Full thread mp Java HotSpot(TM) Client VM (20.6-b01 mixed mode):
"Worker-30" prio=6 tid=0x06514c00 nid=0x1018 in Object.wait() [0x056af000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.eclipse.core.internal.jobs.WorkerPool.sleep(WorkerPool.java:188)
- locked <0x1ad84a90> (a org.eclipse.core.internal.jobs.WorkerPool)
at org.eclipse.core.internal.jobs.WorkerPool.startJob(WorkerPool.java:220)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:50)
......
......
......
......
jstat(JVM statistics Monitoriing Tool):JVM統計信息監視工具
對Java應用程序的資源和性能進行實時的命令行的監控,包括了對Heap size和垃圾回收狀況的監控
命令格式:jstat [ option pid [interval [ s | ms ] [count] ] ]
常用參數說明:
-gcutil 輸出已使用空間占總空間的百分比
-gccapacity 輸出堆中各個區域使用到的最大和最小空間
例如:每隔1秒監控jvm內存一次,共監控5次
C:\Users\Administrator>jstat -gccapacity 1796 1s 5
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 96
13632.0 174720.0 40896.0 4032.0 4032.0 32832.0 27328.0 349568.0 81684.0 81684.0 12288.0 262144.0 80640.0 80640.0 42 97
C:\Users\Administrator>jstat -gcutil 1796 1s 5
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
0.00 0.00 0.52 53.35 99.77 42 0.513 99 38.119 38.632
一些術語的中文解釋:
S0C:年輕代中第一個survivor(倖存區)的容量 (位元組)
S1C:年輕代中第二個survivor(倖存區)的容量 (位元組)
S0U:年輕代中第一個survivor(倖存區)目前已使用空間 (位元組)
S1U:年輕代中第二個survivor(倖存區)目前已使用空間 (位元組)
EC:年輕代中Eden(伊甸園)的容量 (位元組)
EU:年輕代中Eden(伊甸園)目前已使用空間 (位元組)
OC:Old代的容量 (位元組)
OU:Old代目前已使用空間 (位元組)
PC:Perm(持久代)的容量 (位元組)
PU:Perm(持久代)目前已使用空間 (位元組)
YGC:從應用程序啟動到采樣時年輕代中gc次數
YGCT:從應用程序啟動到采樣時年輕代中gc所用時間(s)
FGC:從應用程序啟動到采樣時old代(全gc)gc次數
FGCT:從應用程序啟動到采樣時old代(全gc)gc所用時間(s)
GCT:從應用程序啟動到采樣時gc用的總時間(s)
NGCMN:年輕代(young)中初始化(最小)的大小 (位元組)
NGCMX:年輕代(young)的最大容量 (位元組)
NGC:年輕代(young)中當前的容量 (位元組)
OGCMN:old代中初始化(最小)的大小 (位元組)
OGCMX:old代的最大容量 (位元組)
OGC:old代當前新生成的容量 (位元組)
PGCMN:perm代中初始化(最小)的大小 (位元組)
PGCMX:perm代的最大容量 (位元組)
PGC:perm代當前新生成的容量 (位元組)
S0:年輕代中第一個survivor(倖存區)已使用的占當前容量百分比
S1:年輕代中第二個survivor(倖存區)已使用的占當前容量百分比
E:年輕代中Eden(伊甸園)已使用的占當前容量百分比
O:old代已使用的占當前容量百分比
P:perm代已使用的占當前容量百分比
S0CMX:年輕代中第一個survivor(倖存區)的最大容量 (位元組)
S1CMX :年輕代中第二個survivor(倖存區)的最大容量 (位元組)
ECMX:年輕代中Eden(伊甸園)的最大容量 (位元組)
DSS:當前需要survivor(倖存區)的容量 (位元組)(Eden區已滿)
TT: 持有次數限制
MTT : 最大持有次數限制
jmap( Memory Map for Java):JVM內存映像工具
列印出某個java進程(使用pid)內存內的所有『對象』的情況(如:產生那些對象,及其數量)
命令格式:jmap [ option ] pid
常用參數說明:
-mp:[live,]format=b,file=<filename> 使用二進制形式輸出jvm的heap內容到文件中, live子選項是可選的,假如指定live選項,那麼只輸出活的對象到文件.
-histo[:live] 列印每個class的實例數目,內存佔用,類全名信息. VM的內部類名字開頭會加上前綴」*」. 如果live子參數加上後,只統計活的對象數量.
-F 強迫.在pid沒有相應的時候使用-mp或者-histo參數. 在這個模式下,live子參數無效.
例如:以二進制形式輸入當前堆內存映像到文件data.hprof中
jmap -mp:live,format=b,file=data.hprof 1796
生成的文件可以使用jhat工具進行分析,在OOM(內存溢出)時,分析大對象,非常有用
通過使用如下參數啟動JVM,也可以獲取到mp文件:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./java_pid<pid>.hprof
在jvm發生內存溢出時生成內存映像文件
jhat(JVM Heap Analysis Tool):JVM堆轉儲快照分析工具
用於對JAVA heap進行離線分析的工具,他可以對不同虛擬機中導出的heap信息文件進行分析,如LINUX上導出的文件可以拿到WINDOWS上進行分析,可以查找諸如內存方面的問題。
命令格式:jhat mpfile(jmap生成的文件)
例如:分析jmap導出的內存映像
jhat data.hprof
執行成功後,訪問http://localhost:7000即可查看內存信息,
MAT(Memory Analyzer Tool):一個基於Eclipse的內存分析工具
官網: http://www.eclipse.org/mat/
update:http://download.eclipse.org/mat/1.2/update-site/
這是eclipse的一個插件,安裝後可以打開xxx.hprof文件,進行分析,比jhat更方便使用,有些時候由於線上xxx.hprof文件過大,直接使用jhat進行初步分析了,可以的話拷貝到本地分析效果更佳。
圖形化監控工具:
在JDK安裝目錄bin下面有兩個可視化監控工具
1. JConsole(Java Monitoring and Management Console) 基於JMX的可視化管理工具。
2. VisualVM(All-in-one Java Troubleshooting Tool)隨JDK發布的最強大的運行監視和故障處理程序。
推薦使用VisualVM,他有很多插件,可以更方便的監控運行時JVM
『肆』 如何查看unix 的java內存使用情況
jmap (linux下特有,也是很常用的一個命令)
觀察運行中的jvm物理內存的佔用情況。
參數如下:
-heap :列印jvm heap的情況
-histo: 列印jvm heap的直方圖。其輸出信息包括類名,對象數量,對象佔用大小。
-histo:live : 同上,但是只答應存活對象的情況
-permstat: 列印permanent generation heap情況
命令使用:
jmap -heap 3409
可以觀察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的內存使用情況
輸出內容:
jmap -histo 3409 | jmap -histo:live 3409
可以觀察heap中所有對象的情況(heap中所有生存的對象的情況)。包括對象數量和所佔空間大小。
輸出內容:
寫個腳本,可以很快把佔用heap最大的對象找出來,對付內存泄漏特別有效。
如果結果很多,可以用以下命令輸出到文本文件。
jmap -histo 3409 | jmap -histo:live 3409 > a.txt
jinfo:可以輸出並修改運行時的java 進程的opts。
jps:與unix上的ps類似,用來顯示本地的java進程,可以查看本地運行著幾個java程序,並顯示他們的進程號。
jstat:一個極強的監視VM內存工具。可以用來監視VM內存內的各種堆和非堆的大小及其內存使用量。
jmap:列印出某個java進程(使用pid)內存內的所有'對象'的情況(如:產生那些對象,及其數量)。
jconsole:一個java GUI監視工具,可以以圖表化的形式顯示各種數據。並可通過遠程連接監視遠程的伺服器VM。
詳細:在使用這些工具前,先用JPS命令獲取當前的每個JVM進程號,然後選擇要查看的JVM。
jstat工具特別強大,有眾多的可選項,詳細查看堆內各個部分的使用量,以及載入類的數量。使用時,需加上查看進程的進程id,和所選參數。以下詳細介紹各個參數的意義。
jstat -class pid:顯示載入class的數量,及所佔空間等信息。
jstat -compiler pid:顯示VM實時編譯的數量等信息。
jstat -gc pid:可以顯示gc的信息,查看gc的次數,及時間。其中最後五項,分別是young gc的次數,young gc的時間,full gc的次數,full gc的時間,gc的總時間。
jstat -gccapacity:可以顯示,VM內存中三代(young,old,perm)對象的使用和佔用大小,如:PGCMN顯示的是最小perm的內存使用量,PGCMX顯示的是perm的內存最大使用量,PGC是當前新生成的perm內存佔用量,PC是但前perm內存佔用量。其他的可以根據這個類推, OC是old內純的佔用量。
jstat -gcnew pid:new對象的信息。
jstat -gcnewcapacity pid:new對象的信息及其佔用量。
jstat -gcold pid:old對象的信息。
jstat -gcoldcapacity pid:old對象的信息及其佔用量。
jstat -gcpermcapacity pid: perm對象的信息及其佔用量。
jstat -util pid:統計gc信息統計。
jstat -printcompilation pid:當前VM執行的信息。
除了以上一個參數外,還可以同時加上 兩個數字,如:jstat -printcompilation 3024 250 6是每250毫秒列印一次,一共列印6次,還可以加上-h3每三行顯示一下標題。
jmap是一個可以輸出所有內存中對象的工具,甚至可以將VM 中的heap,以二進制輸出成文本。
命令:jmap -mp:format=b,file=heap.bin
file:保存路徑及文件名
pid:進程編號
?jmap -histo:live pid| less :堆中活動的對象以及大小
?jmap -heap pid : 查看堆的使用狀況信息
jinfo:的用處比較簡單,就是能輸出並修改運行時的java進程的運行參數。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
jconsole是一個用java寫的GUI程序,用來監控VM,並可監控遠程的VM,非常易用,而且功能非常強。使用方法:命令行里打 jconsole,選則進程就可以了。
JConsole中關於內存分區的說明。
Eden Space (heap): 內存最初從這個線程池分配給大部分對象。
Survivor Space (heap):用於保存在eden space內存池中經過垃圾回收後沒有被回收的對象。
Tenured Generation (heap):用於保持已經在 survivor space內存池中存在了一段時間的對象。
Permanent Generation (non-heap): 保存虛擬機自己的靜態(refective)數據,例如類(class)和方法(method)對象。Java虛擬機共享這些類數據。這個區域被分割為只讀的和只寫的,
Code Cache (non-heap):HotSpot Java虛擬機包括一個用於編譯和保存本地代碼(native code)的內存,叫做「代碼緩存區」(code cache)
?jstack ( 查看jvm線程運行狀態,是否有死鎖現象等等信息) : jstack pid : thread mp
?jstat -gcutil pid 1000 100 : 1000ms統計一次gc情況統計100次;
另外推薦一款查看jmap mp 的內存對象工具 MemoryAnalyzer
『伍』 怎樣查看JAVA內存的大小
首先先說一下JVM內存結構問題,JVM為兩塊:PermanentSapce和HeapSpace,其中
Heap = }。PermantSpace負責保存反射對象,一般不用配置。JVM的Heap區可以通過-X參數來設定。
當一個URL被訪問時,內存申請過程如下:
A. JVM會試圖為相關Java對象在Eden中初始化一塊內存區域
B. 當Eden空間足夠時,內存申請結束。否則到下一步
C. JVM試圖釋放在Eden中所有不活躍的對象(這屬於1或更高級的垃圾回收), 釋放後若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區
D. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠時,Survivor區的對象會被移到Old區,否則會被保留在Survivor區
E. 當OLD區空間不夠時,JVM會在OLD區進行完全的垃圾收集(0級)
F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden復制過來的部分對象,導致JVM無法在Eden區為新對象創建內存區域,則出現」out of memory錯誤」
JVM調優建議:
ms/mx:定義YOUNG+OLD段的總尺寸,ms為JVM啟動時YOUNG+OLD的內存大小;mx為最大可佔用的YOUNG+OLD內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
NewSize/MaxNewSize:定義YOUNG段的尺寸,NewSize為JVM啟動時YOUNG的內存大小;MaxNewSize為最大可佔用的YOUNG內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
PermSize/MaxPermSize:定義Perm段的尺寸,PermSize為JVM啟動時Perm的內存大小;MaxPermSize為最大可佔用的Perm內存大小。在用戶生產環境上一般將這兩個值設為相同,以減少運行期間系統在內存申請上所花的開銷。
SurvivorRatio:設置Survivor空間和Eden空間的比例
內存溢出的可能性
1. OLD段溢出
這種內存溢出是最常見的情況之一,產生的原因可能是:
1) 設置的內存參數過小(ms/mx, NewSize/MaxNewSize)
2) 程序問題
單個程序持續進行消耗內存的處理,如循環幾千次的字元串處理,對字元串處理應建議使用StringBuffer。此時不會報內存溢出錯,卻會使系統持續垃圾收集,無法處理其它請求,相關問題程序可通過Thread Dump獲取(見系統問題診斷一章)單個程序所申請內存過大,有的程序會申請幾十乃至幾百兆內存,此時JVM也會因無法申請到資源而出現內存溢出,對此首先要找到相關功能,然後交予程序員修改,要找到相關程序,必須在Apache日誌中尋找。
當Java對象使用完畢後,其所引用的對象卻沒有銷毀,使得JVM認為他還是活躍的對象而不進行回收,這樣累計佔用了大量內存而無法釋放。由於目前市面上還沒有對系統影響小的內存分析工具,故此時只能和程序員一起定位。
2. Perm段溢出
通常由於Perm段裝載了大量的Servlet類而導致溢出,目前的解決辦法:
1) 將PermSize擴大,一般256M能夠滿足要求
2) 若別無選擇,則只能將servlet的路徑加到CLASSPATH中,但一般不建議這么處理
3. C Heap溢出
系統對C Heap沒有限制,故C Heap發生問題時,Java進程所佔內存會持續增長,直到佔用所有可用系統內存
參數說明:
JVM 堆內存(heap)設置選項
參數格式
說 明
設置新對象生產堆內存(Setting the Newgeneration heap size)
-XX:NewSize
通過這個選項可以設置Java新對象生產堆內存。在通常情況下這個選項的數值為1 024的整數倍並且大於1MB。這個值的取值規則為,一般情況下這個值-XX:NewSize是最大堆內存(maximum heap size)的四分之一。增加這個選項值的大小是為了增大較大數量的短生命周期對象
增加Java新對象生產堆內存相當於增加了處理器的數目。並且可以並行地分配內存,但是請注意內存的垃圾回收卻是不可以並行處理的
設置最大新對象生產堆內存(Setting the maximum New generation heap size)
-XX:MaxNewSize
通過這個選項可以設置最大Java新對象生產堆內存。通常情況下這個選項的數值為1 024的整數倍並且大於1MB
其功用與上面的設置新對象生產堆內存-XX:NewSize相同
設置新對象生產堆內存的比例(Setting New heap size ratios)
-XX:SurvivorRatio
新對象生產區域通常情況下被分為3個子區域:伊甸園,與兩個殘存對象空間,這兩個空間的大小是相同的。通過用-XX:SurvivorRatio=X選項配置伊甸園與殘存對象空間(Eden/survivor)的大小的比例。你可以試著將這個值設置為8,然後監控、觀察垃圾回收的工作情況
設置堆內存池的最大值(Setting maximum heap size)
-Xmx
通過這個選項可以要求系統為堆內存池分配內存空間的最大值。通常情況下這個選項的數值為1 024的整數倍並且大於1 MB
一般情況下這個值(-Xmx)與最小堆內存(minimum heap size –Xms)相同,以降低垃圾回收的頻度
取消垃圾回收
-Xnoclassgc
這個選項用來取消系統對特定類的垃圾回收。它可以防止當這個類的所有引用丟失之後,這個類仍被引用時不會再一次被重新裝載,因此這個選項將增大系統堆內存的空間
設置棧內存的大小
-Xss
這個選項用來控制本地線程棧的大小,當這個選項被設置的較大(>2MB)時將會在很大程度上降低系統的性能。因此在設置這個值時應該格外小心,調整後要注意觀察系統的性能,不斷調整以期達到最優
最後說一句,你的機器的連接數設置也至關重要,連接的關閉最好把時間設置的少些,那些連接非常耗費資源。也是引起內存泄露的主要原因。
『陸』 java 虛擬機堆的大小怎樣查看
命令行
java –Xms128m //JVM佔用最小內存
–Xmx512m //JVM佔用最大內存
–XX:PermSize=64m //最小堆大小
–XX:MaxPermSize=128m //最大堆大小
『柒』 java visualvm 堆mp怎麼分析
jmap是java自帶的工具
1. 查看整個JVM內存狀態
jmap -heap [pid]
2. 查看JVM堆中對象詳細佔用情況
jmap -histo [pid]
3. 導出整個JVM 中內存信息,可以利用其它工具打開mp文件分析,例如jdk自帶的visualvm工具
jmap -mp:file=文件名.mp [pid]
『捌』 java反編譯之後怎麼看堆棧里的對象
這個嘛呵呵!java有一個類叫class類,還有MethodConstructorFieldPackage====,很多鳥,這些都是java的一個功能叫做Reflection,這個功能可以同過你給定一個類名探察類的內部,比如說這個類的名字,屬於哪個包繼承哪些類,實現哪些介面,有哪些屬性,有哪些方法,其實eclipse的那個功能就是通過Reflection來實現的我寫個簡單的你去試一下拉,不過具體的就一言難盡拉,你要自己去看java文檔拉這個幾個類是java.lang.Classjava.lang.reflect.*packagedya0201;importjava.util.*;importjava.lang.reflect.*;publicclassRefletion1{publicstaticvoidmain(String[]args){try{Classc=Class.forName("java.util.HashSet");System.out.println(c.getPackage().getName());for(Objecto:c.getMethods()){Methodm=(Method)o;System.out.println(m.getName());}}catch(Exceptione){e.printStackTrace();}}}這里通過一個類名,注意是完整的類名包括了包名,通過類名探察它的有哪些個非私有方法
『玖』 怎樣 查看 java 堆值
堆的值我知道是不能看的,但是你能看到的是堆的使用情況,JVM內存的消耗,GC的時間等,都可以用JVM自帶的工具,bin目錄下的什麼JSTAT,jconsole等都可以,但是用法要上網搜一下
『拾』 java 虛擬機堆的大小怎樣查看(有個疑問)
這個應該沒有查看的辦法,不過用代碼可以查看內存的分配情況:
Runtime.maxMemory();
Runtime.totalMemory();
Runtime.freeMemory();