1. 程式人生 > >jvm java虛擬機 新生代的配置

jvm java虛擬機 新生代的配置

方法區 tools images 轉載 影響 tool 引用 blog avi

目錄(?)[+]

  1. 111 -Xmn參數
  2. 112 第一種情況-Xmx20m -Xms20m -Xmn1m -XXSurvivorRatio2 -XXPrintGCDetails
  3. 113 第二種情況-Xmx20m -Xms20m -Xmn7m -XXSurvivorRatio2 -XXPrintGCDetails
  4. 114 第三種情況-Xmx20m -Xms20m -Xmn15m -XXSurvivorRatio8 -XXPrintGCDetails
  5. 115 -XXNewRatio參數
  6. 116 第四種情況-Xmx20m -Xms20m -XXNewRatio2 -XXPrintGCDetails

1.1.1.1. -Xmn參數

參數-Xmn1m可以用於設置新生代的大小。設置一個較大的新生代會影響老生代的大小,因為這兩者的總和是一定的,這個系統參數對於系統性能以及GC行為有很大的影響,新生代一般設置為整個堆空間的1/31/4左右最合適。

參數-XX:SurvivorRatio用來設置新生代中eden空間和from/to空間的比例,公式如下:

-XX:SurvivorRatio=eden/from =eden/to

解釋:fromto之間的兩塊區間內存是相等的。可以參考

java虛擬機 jvm java堆 方法區 java棧這篇文章,下面的輸出也會印證fromto之間的兩塊區間內存是相等的。

使用不同的堆分配參數確實有很大的影響,下面開始驗證影響。

下面代碼是循環十次每次申請1M的空間一共申請10M,代碼如下:

[java] view plain copy print?
  1. byte[] b = null;
  2. for (int i = 0; i < 10; i++) {
  3. b = new byte[1 * 1024 * 1024];
  4. }
技術分享
byte[] b = null;
for (int i = 0; i < 10; i++) {
b = new byte[1 * 1024 * 1024];
}

1.1.1.2. 第一種情況:-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

配置上面的參數程序的輸出如下:

[GC [DefNew: 512K->256K(768K), 0.0010949 secs] 512K->377K(20224K), 0.0011182 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

def new generation total 768K, used 488K [0x335d0000, 0x336d0000, 0x336d0000)

eden space 512K, 45% used [0x335d0000, 0x3360a2e0, 0x33650000)

from space 256K,100% used [0x33690000, 0x336d0000, 0x336d0000)

to space 256K, 0% used [0x33650000, 0x33650000, 0x33690000)

tenured generation total 19456K, used 10361K[0x336d0000, 0x349d0000, 0x349d0000)

the space 19456K, 53% used [0x336d0000, 0x340ee730, 0x340ee800, 0x349d0000)

compacting perm gen total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

the space 12288K, 1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

ro space 10240K, 45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

rw space 12288K, 54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

設置的edenfrom的比例是2:1 from=to 這裏前面說過,輸出也確實證明是相等的。所以eden512K,新生代我們分配的是1M=512K+256K+256k=1024K=1M,總的可用的新生代為512K+256K=768K;

由於新生代的eden區域的內存為512K我們每次申請的空間是1M,所以沒有辦法容納,因此觸發了一次GC垃圾回收,對eden區域的內存進行了部分的回收,新生代沒有內存容納1M的內存還是不夠存儲,所以數組都被分配到老生代,老生代最終占用了10361K空間。

1.1.1.3. 第二種情況:-Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

第二種情況將新生代內存擴大到7M,輸出如下:

[GC [DefNew: 2795K->1498K(5376K), 0.0018315 secs] 2795K->1498K(18688K), 0.0018637 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 4687K->1024K(5376K), 0.0011140 secs] 4687K->1498K(18688K), 0.0011327 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 4125K->1024K(5376K), 0.0004712 secs] 4599K->1498K(18688K), 0.0004903 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

def new generation total 5376K, used 3163K [0x335d0000, 0x33cd0000, 0x33cd0000)

eden space 3584K, 59% used [0x335d0000, 0x337e6d38, 0x33950000)

from space 1792K, 57% used [0x33b10000, 0x33c10010, 0x33cd0000)

to space 1792K, 0% used [0x33950000, 0x33950000, 0x33b10000)

tenured generation total 13312K, used 474K[0x33cd0000, 0x349d0000, 0x349d0000)

the space 13312K, 3% used [0x33cd0000, 0x33d468e0, 0x33d46a00, 0x349d0000)

compacting perm gen total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

the space 12288K, 1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

ro space 10240K, 45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

rw space 12288K, 54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

在這個參數下eden的內存為3584K所以可以有空間存儲數組,所以數組先被分配到這個eden區,但是還不能完全預留全部的10M內存,所以運行的時候產生了3GC垃圾回收,因為程序申請內存的時候,變量失去了上一次的引用指針。所以是在新生代中進行GC垃圾回收。最終的結果:所有的內存都被分配到新生代進行,通過GC保證了新生代有足夠的空間存儲。而沒有進入老年代,只是在GC過程中,部分新生對象晉升到老年代。

1.1.1.4. 第三種情況:-Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 -XX:+PrintGCDetails

第三種情況將新生代內存擴大到15M,輸出如下:

Heap

def new generation total 13824K, used 11223K [0x335d0000, 0x344d0000, 0x344d0000)

eden space 12288K, 91% used [0x335d0000, 0x340c5f50, 0x341d0000)

from space 1536K, 0% used [0x341d0000, 0x341d0000, 0x34350000)

to space 1536K, 0% used [0x34350000, 0x34350000, 0x344d0000)

tenured generation total 5120K, used 0K[0x344d0000, 0x349d0000, 0x349d0000)

the space 5120K, 0% used [0x344d0000, 0x344d0000, 0x344d0200, 0x349d0000)

compacting perm gen total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

the space 12288K, 1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

ro space 10240K, 45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

rw space 12288K, 54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

在這次的測試中,新生代被分配15M內存,eden的內存是12288K所有這個區域完全可以容納10M的內存數組,所以所有的分配都是在eden直接進行,並沒有觸發GC垃圾回收,因此from/to和老年代tenured使用率都是0.

通過上面的例子,發現不同的堆分配策略對系統執行的影響還是很大。所以在實際開發中,還是要合理的設置值,基本策略:盡可能將對象預留在新生代,減少老年代GC次數。(第一種情況對象都被分配到老年代,老年代肯定要進行GC垃圾回收)

1.1.1.5. -XX:NewRatio參數

-XX:NewRatio參數主要設置新生代和老年代的比例。公式如下:

-XX:NewRatio=老年代/新生代

1.1.1.6. 第四種情況:-Xmx20m -Xms20m -XX:NewRatio=2 -XX:+PrintGCDetails

第四種參數設置為:-Xmx20m -Xms20m -XX:NewRatio=2 -XX:+PrintGCDetails 程序的輸出如下:

[GC [DefNew: 4899K->474K(6144K), 0.0016090 secs] 4899K->1498K(19840K), 0.0016426 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 5768K->0K(6144K), 0.0011308 secs] 6792K->2522K(19840K), 0.0011490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

def new generation total 6144K, used 1134K [0x335d0000, 0x33c70000, 0x33c70000)

eden space 5504K, 20% used [0x335d0000, 0x336eb8c8, 0x33b30000)

from space 640K, 0% used [0x33b30000, 0x33b30088, 0x33bd0000)

to space 640K, 0% used [0x33bd0000, 0x33bd0000, 0x33c70000)

tenured generation total 13696K, used 2522K [0x33c70000, 0x349d0000, 0x349d0000)

the space 13696K, 18% used [0x33c70000, 0x33ee6878, 0x33ee6a00, 0x349d0000)

compacting perm gen total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

the space 12288K, 1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

ro space 10240K, 45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

rw space 12288K, 54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

因為堆空間分配的內存為20M,老年代和新生代比例我們設置的是2:1,所以新生代的內存大約是6144K 老年代的內存是13696K由於新生代Gc的時候,from/to的內存容納不下任何一個1m數組對象,影響了新生代的正常回收,所以對象都跑到老年代空間了。因此導致兩個1MB數組進入老年代,(新生代GC,還有1M數組幸存,按理說應進入from/to但是from/to只有640K空間不足)

註意:

-XX:SurvivorRatio可以設置eden區與Survivor區比例,-XX:NewRatio可以設置老年代新生代的比例。

完成的公式如下圖所示:

技術分享

jvm java虛擬機 新生代的配置