Trace跟蹤參數(shù)
- 打印GC的簡要信息
- -verbose:gc
- -XX:+printGC
- [GC 4790K->374K(15872K), 0.0001606 secs]
- [GC 4790K->374K(15872K), 0.0001474 secs]
- [GC 4790K->374K(15872K), 0.0001563 secs]
- [GC 4790K->374K(15872K), 0.0001682 secs]
- 打印GC詳細(xì)信息
- -XX:+PrintGCDetails
- 打印CG發(fā)生的時間戳
- -XX:+PrintGCTimeStamps
- [GC[DefNew: 4416K->0K(4928K), 0.0001897 secs] 4790K->374K(15872K), 0.0002232 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
- 指定GC log的位置响鹃,以文件輸出:幫助開發(fā)人員分析問題
- -Xloggc:log/gc.log
- 每次進(jìn)行一次GC后城豁,都打印堆信息
- -XX:+PrintHeapAtGC
- 監(jiān)控類的加載
- -XX:+TraceClassLoading
- 按下Ctrl+Break后,打印類的信息:分別顯示:序號、實例數(shù)量车要、總大小、類型
-
-XX:+PrintClassHistogram
打印類信息.png
-
堆的分配參數(shù)
-
指定最大堆和最小堆
- -Xmx –Xms
- -Xmx20m -Xms5m 運行代碼:
- 指定最大堆20M牺弹,最小堆5M
System.out.print("Xmx="); System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); System.out.print("free mem="); System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M"); System.out.print("total mem="); System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M"); 結(jié)果: Xmx=19.375M free mem=4.342750549316406M total mem=4.875M
- 指定最大堆20M腕侄,最小堆5M,分配了1M空間給數(shù)組
byte[] b=new byte[1*1024*1024]; System.out.println("分配了1M空間給數(shù)組"); System.out.print("Xmx="); System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); System.out.print("free mem="); System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M"); //Java會盡可能維持在最小堆 System.out.print("total mem="); System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M"); 結(jié)果: 分配了1M空間給數(shù)組 Xmx=19.375M free mem=3.4791183471679688M total mem=4.875M
- 指定最大堆20M订雾,最小堆5M肢预,分配了4M空間給數(shù)組
b=new byte[4*1024*1024]; System.out.println("分配了4M空間給數(shù)組"); System.out.print("Xmx="); System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); System.out.print("free mem="); System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M"); System.out.print("total mem="); System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M"); 結(jié)果: 分配了4M空間給數(shù)組 Xmx=19.375M free mem=3.5899810791015625M //總內(nèi)存變多了 total mem=9.00390625M
- 指定最大堆20M,最小堆5M洼哎,回收內(nèi)存
b=new byte[4*1024*1024]; System.out.println("分配了4M空間給數(shù)組"); System.out.print("Xmx="); System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); System.out.print("free mem="); System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M"); System.out.print("total mem="); System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M"); System.gc(); System.out.println("回收內(nèi)存"); System.out.print("Xmx="); System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M"); System.out.print("free mem="); System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M"); System.out.print("total mem="); System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M"); 結(jié)果: 分配了4M空間給數(shù)組 Xmx=19.375M free mem=3.5899810791015625M //總內(nèi)存變多了 total mem=9.00390625M 回收內(nèi)存 Xmx=19.375M //空閑內(nèi)存增多 free mem=6.354591369628906M total mem=10.75390625M
-
設(shè)置新生代大小
- -Xmn
-
新生代(eden+2*s)和老年代(不包含永久區(qū))的比值
- 4 表示 新生代:老年代=1:4烫映,即年輕代占堆的1/5
- -XX:NewRatio
-
設(shè)置兩個Survivor區(qū)和eden的比
- 8表示 兩個Survivor :eden=2:8,即一個Survivor占年輕代的1/10
- -XX:SurvivorRatio
-
OOM時導(dǎo)出堆到文件
- -XX:+HeapDumpOnOutOfMemoryError
-
導(dǎo)出OOM的路徑
- -XX:+HeapDumpPath
- -Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump
-
在OOM時噩峦,執(zhí)行一個腳本
- -XX:OnOutOfMemoryError
總結(jié):
- 根據(jù)實際事情調(diào)整新生代和幸存代的大小
- 官方推薦新生代占堆的3/8
- 幸存代占新生代的1/10
- 在OOM時锭沟,記得Dump出堆,確笔恫梗可以排查現(xiàn)場問題
永久區(qū)分配參數(shù)
- 設(shè)置永久區(qū)的初始空間和最大空間
- -XX:PermSize -XX:MaxPermSize
- 使用CGLIB等庫的時候族淮,可能會產(chǎn)生大量的類,這些類凭涂,有可能撐爆永久區(qū)導(dǎo)致OOM
棧的分配參數(shù)
- 棧大小分配
- -Xss
- 通常只有幾百K
- 決定了函數(shù)調(diào)用的深度
- 每個線程都有獨立的椬@保空間
- 局部變量、參數(shù)分配在棧上
public class TestStackDeep { private static int count=0; public static void recursion(long a,long b,long c){ long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10; count++; recursion(a,b,c); } public static void main(String args[]){ try{ recursion(0L,0L,0L); }catch(Throwable e){ System.out.println("deep of calling = "+count); e.printStackTrace(); } } } 結(jié)果: 遞歸調(diào)用 -Xss128K deep of calling = 701 java.lang.StackOverflowError -Xss256K deep of calling = 1817 java.lang.StackOverflowError
- -Xss