內存分配規則
阿新 • • 發佈:2017-10-05
class min object 收集 log 連續 cde def null
對象優先在Eden分配
大多數情況下,對象會在新生代Eden區中分配,當Eden區中沒有足夠空間時,虛擬機將發起一次Minor GC。
package com.wjz.demo; public class HeapOOM { static class OOMObject {} /** * 使用 Serial / Serial Old 組合收集器 * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC * @paramargs */ private static final int _1MB = 1024*1024; public static void main(String[] args) { byte[] b1, b2, b3, b4; b1 = new byte[2*_1MB]; b2 = new byte[2*_1MB]; b3 = new byte[2*_1MB]; b4 = new byte[4*_1MB]; // 此處會出現一次Minor GC } }
運行結果
[GC [DefNew: 6993K->554K(9216K), 0.0212177 secs] 6993K->6698K(19456K), 0.0318550 secs] [Times: user=0.00 sys=0.02, real=0.03 secs] Heap defnew generation total 9216K, used 4978K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 56% used [0x00000000f9a00000, 0x00000000f9e51fa0, 0x00000000fa200000) from space 1024K, 54% used [0x00000000fa300000, 0x00000000fa38a8b0, 0x00000000fa400000) to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 60% used[0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000) compacting perm gen total 21248K, used 2556K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb07f258, 0x00000000fb07f400, 0x00000000fc2c0000) No shared spaces configured.
eden space 8192K:新生代Eden區
from space 1024K:新生代from survivor區
to space 1024K:新生代to survivor區
the space 10240K:老年代區
結果分析
新生代內存占用量由6993K降到554K,總內存占用量由6993K升到6998K幾乎沒有變化。3個2M對象分配內存時放入了新生代Eden區,此時Eden區還剩2M左右的內存空間, 又來了一個4M對象想放進Eden區當時顯然不可能,觸發了一次Minor GC,復制算法開始將Eden區的對象復制到from survivor區,但是from survivor區只有1M空間,所以 只能將這3個2M對象通過分配擔保轉移到老年代中。4M對象被分配到了Eden區。
大對象直接進入老年代
大對象是指需要大量連續空間的對象如字符串和數組。
package com.wjz.demo; public class HeapOOM { static class OOMObject {} /** * 使用 Serial / Serial Old 收集器 * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC * -XX:PretenureSizeThreshold=3145728(僅Serial、PreNew有效) * @param args */ private static final int _1MB = 1024*1024; public static void main(String[] args) { byte[] b1; b1 = new byte[4*_1MB]; } }
運行結果
Heap def new generation total 9216K, used 1013K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 12% used [0x00000000f9a00000, 0x00000000f9afd518, 0x00000000fa200000) from space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000) to space 1024K, 0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000) tenured generation total 10240K, used 4096K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 40% used [0x00000000fa400000, 0x00000000fa800010, 0x00000000fa800200, 0x00000000fae00000) compacting perm gen total 21248K, used 2553K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb07e5d8, 0x00000000fb07e600, 0x00000000fc2c0000) No shared spaces configured.
結果分析
新生代Eden和survivor區幾乎沒有使用,老年區占用了40%,因為大於3M的對象直接分配到了老年代中。
長期存活的對象進入老年代
設置-XX:MaxTenuringThreshold參數設置對象進入老年代的年齡閾值。
package com.wjz.demo; public class HeapOOM { static class OOMObject {} /** * 使用 Serial / Serial Old 收集器 * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC * -XX:MaxTenuringThreshold=1 -XX:+PrintTenuringDistribution * @param args */ private static final int _1MB = 1024*1024; public static void main(String[] args) { byte[] b1, b2, b3, b4; b1 = new byte[_1MB/4]; b2 = new byte[4*_1MB]; b3 = new byte[4*_1MB]; b3 = null; b4 = new byte[4*_1MB]; } }
運行結果
[GC [DefNew Desired survivor size 524288 bytes, new threshold 1 (max 1) - age 1: 829632 bytes, 829632 total : 5201K->810K(9216K), 0.0036339 secs] 5201K->4906K(19456K), 0.0036706 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC [DefNew Desired survivor size 524288 bytes, new threshold 1 (max 1) - age 1: 256 bytes, 256 total : 5234K->0K(9216K), 0.0013901 secs] 9330K->4906K(19456K), 0.0014093 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 4260K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000) eden space 8192K, 52% used [0x00000000f9a00000, 0x00000000f9e28fd0, 0x00000000fa200000) from space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200100, 0x00000000fa300000) to space 1024K, 0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000) tenured generation total 10240K, used 4906K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000) the space 10240K, 47% used [0x00000000fa400000, 0x00000000fa8ca8d0, 0x00000000fa8caa00, 0x00000000fae00000) compacting perm gen total 21248K, used 2556K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000) the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb07f258, 0x00000000fb07f400, 0x00000000fc2c0000) No shared spaces configured.
內存分配規則