码迷,mamicode.com
首页 > 其他好文 > 详细

内存分配规则

时间:2017-10-05 10:56:08      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:real   cti   阈值   max   虚拟   ota   运行   res   serial   

对象优先在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
     * @param args
     */
    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
 def new 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.

 

内存分配规则

标签:real   cti   阈值   max   虚拟   ota   运行   res   serial   

原文地址:http://www.cnblogs.com/BINGJJFLY/p/7628674.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!