3_jvm_配置參數

1.Trace跟蹤參數



GC的簡要信息:

-verbose:gc

-xx:PrintGC

[GC4790K->374K(15872K), 0.0001606 secs]

初始堆空間4790K 到 374K  回收將近4M    整個堆的大小在16m左右 ,0.0001606 secs:用時

打印GC的詳細信息:

-xx:PrintGCDetails ------>打印GC的詳細信息

-xx:PrintGCTimeStamps---->打印GC發生的時間戳

[GC [PSYoungGen: 32640K->584K(38016K)] 32640K->584K(124864K), 0.0007259 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

  • real —— 程序從開始到結束所用的時鐘時間。這個時間包括其他進程使用的時間片和進程阻塞的時間(比如等待 I/O 完成)。

  • user —— 進程執行用戶態代碼(核心之外)所使用的時間。這是執行此進程所使用的實際 CPU 時間,其他進程和此進程阻塞的時間並不包括在內。在垃圾收集的情況下,表示 GC 線程執行所使用的 CPU 總時間。

  • sys —— 進程在內核態消耗的 CPU 時間,即在內核執行系統調用或等待系統事件所使用的 CPU 時間。

user + sys 時間告訴我們程序執行實際使用的 CPU 時間。注意這裏指所有的 CPU,因此如果在進程裏有多個線程的話,這個時間可能會超過 real 所表示的時鐘時間。

例1:

[Times: user=11.53 sys=1.38, real=1.03 secs]

在這個例子中,user + sys 時間的和比 real 時間要大,這主要是因爲日誌時間是從 JVM 中獲得的,而這個 JVM 在多核的處理器上被配置了多個 GC 線程,由於多個線程並行地執行 GC,因此整個 GC 工作被這些線程共享,最終導致實際的時鐘時間(real)小於總的 CPU 時間(user + sys)。

例2:

[Times: user=0.09 sys=0.00, real=0.09 secs]

上面的例子中的 GC 時間是從 Serial 垃圾收集器 (串行垃圾收集器)中獲得的。由於 Serial 垃圾收集器是使用單線程進行垃圾收集的,因此 real 時間等於 user 和 sys 時間之和。

總結

在做性能優化時,我們一般採用 real 時間來優化程序。因爲最終用戶只關心點擊頁面發出請求到頁面上展示出內容所花的時間,也就是響應時間,而不關心你到底使用了多少個 GC 線程或者處理器。但並不是說 sys 和 user 兩個時間不重要,當我們想通過增加 GC 線程或者 CPU 數量來減少 GC 停頓時間時,可以參考這兩個時間。



 PSYoungGen      total 669248K, used 483060K [0x00000007d5960000, 0x00000007fe7c0000, 0x0000000800000000)
  eden space 668416K, 72% used [0x00000007d5960000,0x00000007f311d320,0x00000007fe620000)
  from space 832K, 0% used [0x00000007fe6f0000,0x00000007fe6f0000,0x00000007fe7c0000)
  to   space 832K, 0% used [0x00000007fe620000,0x00000007fe620000,0x00000007fe6f0000)
 ParOldGen       total 86848K, used 488K [0x0000000780c00000, 0x00000007860d0000, 0x00000007d5960000)
  object space 86848K, 0% used [0x0000000780c00000,0x0000000780c7a060,0x00000007860d0000)
 PSPermGen       total 21248K, used 2595K [0x000000077ba00000, 0x000000077cec0000, 0x0000000780c00000)
  object space 21248K, 12% used [0x000000077ba00000,0x000000077bc88c70,0x000000077cec0000)


 PSYoungGen:新生代      ParOldGen:老年代     PSPermGen :永久區

PSYoungGen --->total  (669248K) = eden space(668416K)+from space(832K);

total  (669248K)+缺省(複製算法所耗)   = (0x00000007fe7c0000-0x00000007d5960000)/1024/1024 


-XX:+PrintGCDetails -Xloggc:log/gc.log (注:項目路徑下保證有log文件夾)
-Xloggc:log/gc.log
指定GC log的位置,以文件輸出
幫助開發人員分析問題

-XX:+PrintHeapAtGC:
每次一次GC後,都打印堆信息
-XX:+TraceClassLoading:
監控類的加載
-XX:+PrintClassHistogram
按下Ctrl+Break後,打印類的信息

num    #instances         #bytes  class name
序號       實例數量       總大小              類型

1:        890617      470266000    [B

2:        890643       21375432    java.util.HashMap$Node

3:        890608       14249728    java.lang.Long

4:            13        8389712         [Ljava.util.HashMap$Node;

5:          2062         371680        [C

6:           463          41904          java.lang.Class




2.堆的分配參數

-Xmx –Xms
-指定最大堆和最小堆
-java儘可能維持在最小堆
Xmx20m-Xms5m 運行代碼:

System.out.print("Xmx=");
System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M");
  17.8125M 系統最大內存


System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M");
6.14300537109375M    系統當前空閒 可用的內存

System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M");

6.875M 系統一共現在分配的空間 總空間
已經使用    6.875M - 6.14300537109375M = 0.7 M (大約)
-----------------------------------------------------------------------------------------------------------
byte[] b=new byte[1*1024*1024];

System.out.print("Xmx=");
System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M");
  17.8125M 系統最大內存


System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M");
5.2031097412109375M   系統當前空閒 可用的內存

System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M");
6.875M 系統一共現在分配的空間 總空間

                            前面代碼所得:已經使用    6.875M - 6.14300537109375M = 0.7 M (大約)
當前代碼所得:已經使用  6.875M - 5.2031097412109375M= 1.7M(大約)多使用了1M

-------------------------------------------------------------------------
byte[] b=new byte[4*1024*1024];

System.out.print("Xmx=");
System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M");
  17.8125M 系統最大內存


System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M");
6.2054901123046875M   系統當前空閒 可用的內存

System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M");
10.9375M 系統一共現在分配的空間 總空間

                        前面代碼所得:已經使用    6.875M - 6.14300537109375M = 0.7 M (大約)
當前代碼所得:已經使用  10.9375M - 6.2054901123046875M= 4.7M(大約)(多使用了4M)
注:這裏總內存變多了 做了擴容gc後如果內存還是不夠,會進一步擴容

-------------------------------------------------------------------------
byte[] b=new byte[4*1024*1024];
System.gc();
System.out.print("Xmx=");
System.out.println(Runtime.getRuntime().maxMemory()/1024.0/1024+"M");
  17.8125M 系統最大內存


System.out.print("free mem=");
System.out.println(Runtime.getRuntime().freeMemory()/1024.0/1024+"M");
6.2950897216796875M   (6.2054901123046875M:不做GC前的大小   系統當前空閒 可用的內存

System.out.print("total mem=");
System.out.println(Runtime.getRuntime().totalMemory()/1024.0/1024+"M");
10.9375M 系統一共現在分配的空間 總空間

                       相比之前空閒內存變大了 



-Xmn: 設置新生代大小
-XX:NewRatio:
新生代(eden+2*s)和老年代(不包含永久區)的比值
4 表示 新生代:老年代=1:4,即年輕代佔堆的1/5

-XX:SurvivorRatio
設置兩個Survivor區和eden的比
8表示 兩個Survivor :eden=2:8,即一個Survivor佔年輕代的1/10

設置新生代大小爲1M
-Xmx20m -Xms20m -Xmn1m  -XX:+PrintGCDetails

  byte[] b=null;
  for(int i=0;i<10;i++)
  {
      b=new byte[1*1024*1024];
  }
   
運行結果



Heap
 PSYoungGen      total 896K, used 673K [0x00000000fff00000, 0x0000000100000000, 0x0000000100000000)
  eden space 768K, 87% used [0x00000000fff00000,0x00000000fffa8420,0x00000000fffc0000)
  from space 128K, 0% used [0x00000000fffe0000,0x00000000fffe0000,0x0000000100000000)
  to   space 128K, 0% used [0x00000000fffc0000,0x00000000fffc0000,0x00000000fffe0000)
 ParOldGen       total 19456K, used 10240K [0x00000000fec00000, 0x00000000fff00000, 0x00000000fff00000)
  object space 19456K, 52% used [0x00000000fec00000,0x00000000ff6000a0,0x00000000fff00000)
 PSPermGen       total 21248K, used 2591K [0x00000000f9a00000, 0x00000000faec0000, 0x00000000fec00000)
  object space 21248K, 12% used [0x00000000f9a00000,0x00000000f9c87cf0,0x00000000faec0000)


1.沒有觸發GC
2. 新生代只有768k 不夠放1M 所以全部都被放到了老年代


新生代 調整到了15M
-Xmx20m -Xms20m -Xmn15m  -XX:+PrintGCDetails

  byte[] b=null;
   for(int i=0;i<10;i++)
   {
       b=new byte[1*1024*1024];
   }
   


Heap
 PSYoungGen      total 13440K, used 11449K [0x00000000ff100000, 0x0000000100000000, 0x0000000100000000)
  eden space 11520K, 99% used [0x00000000ff100000,0x00000000ffc2e418,0x00000000ffc40000)
  from space 1920K, 0% used [0x00000000ffe20000,0x00000000ffe20000,0x0000000100000000)
  to   space 1920K, 0% used [0x00000000ffc40000,0x00000000ffc40000,0x00000000ffe20000)
 ParOldGen       total 5120K, used 0K [0x00000000fea00000, 0x00000000fef00000, 0x00000000ff100000)
  object space 5120K, 0% used [0x00000000fea00000,0x00000000fea00000,0x00000000fef00000)
 PSPermGen       total 21248K, used 2591K [0x00000000f9800000, 0x00000000facc0000, 0x00000000fea00000)
  object space 21248K, 12% used [0x00000000f9800000,0x00000000f9a87cf0,0x00000000facc0000)


1.沒有觸發GC
2.全部都分配到了eden
3.老年代  沒有使用



新生代 調整到了7M
-Xmx20m -Xms20m -Xmn7m  -XX:+PrintGCDetails

  byte[] b=null;
   for(int i=0;i<10;i++)
   {
       b=new byte[1*1024*1024];
   }
   


[GC [PSYoungGen: 4938K->600K(6272K)] 4938K->1624K(19584K), 0.0006429 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 4972K->568K(6272K)] 5996K->2616K(19584K), 0.0005536 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 
PSYoungGen      total 6272K, used 2709K [0x00000000ff900000, 0x0000000100000000, 0x0000000100000000)
  eden space 5376K, 39% used [0x00000000ff900000,0x00000000ffb177a8,0x00000000ffe40000)
  from space 896K, 63% used [0x00000000fff20000,0x00000000fffae030,0x0000000100000000)
  to   space 896K, 0% used [0x00000000ffe40000,0x00000000ffe40000,0x00000000fff20000)
 
ParOldGen       total 13312K, used 2048K [0x00000000fec00000, 0x00000000ff900000, 0x00000000ff900000)
  object space 13312K, 15% used [0x00000000fec00000,0x00000000fee00020,0x00000000ff900000)
 
PSPermGen       total 21248K, used 2594K [0x00000000f9a00000, 0x00000000faec0000, 0x00000000fec00000)
  object space 21248K, 12% used [0x00000000f9a00000,0x00000000f9c88938,0x00000000faec0000)


1.發生了兩次GC
2.有部分在老年代,s0 s1 太小 需要老年代擔保



新生代 調整到了7M
-Xmx20m -Xms20m -Xmn7m  -XX:SurvivorRatio=2  -XX:+PrintGCDetails

  byte[] b=null;
   for(int i=0;i<10;i++)
   {
       b=new byte[1*1024*1024];
   }

[GC [PSYoungGen: 2766K->1592K(5376K)] 2766K->1592K(18688K), 0.0008951 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 4850K->1560K(5376K)] 4850K->1560K(18688K), 0.0008494 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC [PSYoungGen: 4660K->1544K(5376K)] 4660K->1544K(18688K), 0.0005483 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 5376K, used 3646K [0x00000000ff900000, 0x0000000100000000, 0x0000000100000000)
  eden space 3584K, 58% used [0x00000000ff900000,0x00000000ffb0dac8,0x00000000ffc80000)
  from space 1792K, 86% used [0x00000000ffc80000,0x00000000ffe02030,0x00000000ffe40000)
  to   space 1792K, 0% used [0x00000000ffe40000,0x00000000ffe40000,0x0000000100000000)
 ParOldGen       total 13312K, used 0K [0x00000000fec00000, 0x00000000ff900000, 0x00000000ff900000)
  object space 13312K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff900000)
 PSPermGen       total 21248K, used 2594K [0x00000000f9a00000, 0x00000000faec0000, 0x00000000fec00000)
  object space 21248K, 12% used [0x00000000f9a00000,0x00000000f9c88938,0x00000000faec0000)

1.發生了3次GC
2.s0 ,s1增大


-XX:+HeapDumpOnOutOfMemoryError
OOM時導出堆到文件
-XX:+HeapDumpPath
導出OOM的路徑
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump
Vector v=newVector();
       for(int i=0;i<25;i++)
           v.add(new byte[1*1024*1024]);




-XX:OnOutOfMemoryError
在OOM時,執行一個腳本
"-XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p“
當程序OOM時,在D:/a.txt中將會生成線程的dump
可以在OOM時,發送郵件,甚至是重啓程序

D:/tools/jdk1.7_40/bin/jstack -F %1 >D:/a.txt




總結:
根據實際事情調整新生代和倖存代的大小
官方推薦新生代佔堆的3/8
倖存代佔新生代的1/10
在OOM時,記得Dump出堆,確保可以排查現場問題




-XX:PermSize  -XX:MaxPermSize
設置永久區的初始空間和最大空間
他們表示,一個系統可以容納多少個類型 (一般幾百kb


如果堆空間沒有用完也拋出了OOM有可能是永久區導致的



3.棧的分配參數

-Xss
通常只有幾百K
決定了函數調用的深度
每個線程都有獨立的棧空間  (越小容納的線程越多)
局部變量、參數 分配在棧上


public static void test(long a,long b,long c){
count++;
test(a,b,c);
}
public static void main(String args[]){
try{
test(0L,0L,0L);
}catch(Throwable e){
System.out.println("deep of calling = "+count);
e.printStackTrace();
}
}

遞歸調用

-Xss128K

deep of calling = 685

java.lang.StackOverflowError



遞歸調用

-Xss128K

deep of calling = 1708

java.lang.StackOverflowError




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章