内存分配与回收策略

1. 对象优先分配在Eden区

当Eden区没有足够的内存空间时,发起一次Monitor GC。

 private static final int M= 1024 * 1024;

    public static void main(String[] arg) {

        byte[] a1 = new byte[2 * M];

        byte[] a2 = new byte[2 * M];

        byte[] a3 = new byte[2 * M];

        byte[] a4 = new byte[4 * M];

    }
[GC [DefNew: 6487K->148K(9216K), 0.0094068 secs] 6487K->6293K(19456K), 0.0094970 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 

Heap

 def new generation   total 9216K, used 4408K [0x315e0000, 0x31fe0000, 0x31fe0000)

  eden space 8192K,  52% used [0x315e0000, 0x31a08fe0, 0x31de0000)

  from space 1024K,  14% used [0x31ee0000, 0x31f053f0, 0x31fe0000)

  to   space 1024K,   0% used [0x31de0000, 0x31de0000, 0x31ee0000)

 tenured generation   total 10240K, used 6144K [0x31fe0000, 0x329e0000, 0x329e0000)

   the space 10240K,  60% used [0x31fe0000, 0x325e0030, 0x325e0200, 0x329e0000)

 compacting perm gen  total 12288K, used 378K [0x329e0000, 0x335e0000, 0x369e0000)

   the space 12288K,   3% used [0x329e0000, 0x32a3e920, 0x32a3ea00, 0x335e0000)

    ro space 10240K,  54% used [0x369e0000, 0x36f5e4a8, 0x36f5e600, 0x373e0000)

    rw space 12288K,  55% used [0x373e0000, 0x37a822a0, 0x37a82400, 0x37fe0000)

2. 大对象直接进入老年代。

虚拟机提供了一个参数:-XX:PretenureSizeThreshold,用来设定大对象直接分配到老年代。这个参数只对Serial和ParNew有效。


public static void main() {

    byte[] a4 = new byte[4 * M];

}

Heap

 def new generation   total 9216K, used 507K [0x315e0000, 0x31fe0000, 0x31fe0000)

  eden space 8192K,   6% used [0x315e0000, 0x3165ef38, 0x31de0000)

  from space 1024K,   0% used [0x31de0000, 0x31de0000, 0x31ee0000)

  to   space 1024K,   0% used [0x31ee0000, 0x31ee0000, 0x31fe0000)

 tenured generation   total 10240K, used 4096K [0x31fe0000, 0x329e0000, 0x329e0000)

   the space 10240K,  40% used [0x31fe0000, 0x323e0010, 0x323e0200, 0x329e0000)

 compacting perm gen  total 12288K, used 378K [0x329e0000, 0x335e0000, 0x369e0000)

   the space 12288K,   3% used [0x329e0000, 0x32a3e9f8, 0x32a3ea00, 0x335e0000)

    ro space 10240K,  54% used [0x369e0000, 0x36f5e4a8, 0x36f5e600, 0x373e0000)

    rw space 12288K,  55% used [0x373e0000, 0x37a822a0, 0x37a82400, 0x37fe0000)


3. 长期存活的对象将进入老年代

可以通过参数:-XX:MaxTenuringThreshold设置。


public static void main() {


    byte[] a1 = new byte[M / 4];

    byte[] a2 = new byte[4 * M];

    byte[] a3 = new byte[4 * M];

    byte[] a3 = null;

    byte[] a3 = new byte[4 * M];

}

[GC [Tenured: 8192K->4501K(10240K), 0.3121115 secs] 8791K->4501K(19456K), [Perm : 378K->378K(12288K)], 0.3121796 secs] [Times: user=0.02 sys=0.01, real=0.31 secs] 

Heap

 def new generation   total 9216K, used 327K [0x315e0000, 0x31fe0000, 0x31fe0000)

  eden space 8192K,   4% used [0x315e0000, 0x31631f98, 0x31de0000)

  from space 1024K,   0% used [0x31de0000, 0x31de0000, 0x31ee0000)

  to   space 1024K,   0% used [0x31ee0000, 0x31ee0000, 0x31fe0000)

 tenured generation   total 10240K, used 8597K [0x31fe0000, 0x329e0000, 0x329e0000)

   the space 10240K,  83% used [0x31fe0000, 0x32845420, 0x32845600, 0x329e0000)

 compacting perm gen  total 12288K, used 378K [0x329e0000, 0x335e0000, 0x369e0000)

   the space 12288K,   3% used [0x329e0000, 0x32a3eaf8, 0x32a3ec00, 0x335e0000)

    ro space 10240K,  54% used [0x369e0000, 0x36f5e4a8, 0x36f5e600, 0x373e0000)

    rw space 12288K,  55% used [0x373e0000, 0x37a822a0, 0x37a82400, 0x37fe0000)

 参数值为:1时。

参数值为:15时。

4.动态对象年龄判断

如果Survivor中相同年龄的对象占到此空间的一半,那么改年龄和大于该年龄的对象放到老年区。

5. 空间分配担保

 在发生Minor GC时,会计算每次进入老年区的平均大小是否大于老年区空间的剩余大小,如果大于则进行一次Full GC。

对象分配规则

1.对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。

2.大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。

3.长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。

4.动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。

5.空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值