美文网首页
深入理解JAVA虚拟机3-内存分配策略

深入理解JAVA虚拟机3-内存分配策略

作者: 半夏丨微凉丶 | 来源:发表于2019-11-06 15:42 被阅读0次

    对象优先在Eden区分配

    新创建的对象在Eden区分配,当Eden内存不足时,会触发一次Minor GC。-XX:+PrintGCDetails 打印内存回收日志

             // -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8
            byte[] allocation1;
            allocation1= new byte[4 * _1MB];
    

    打印日志

    [GC (Allocation Failure) [PSYoungGen: 6710K->1016K(9216K)] 6710K->1427K(19456K), 0.0020683 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    Heap
     PSYoungGen      total 9216K, used 7397K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
      eden space 8192K, 77% used [0x00000000ff600000,0x00000000ffc3b688,0x00000000ffe00000)
      from space 1024K, 99% used [0x00000000ffe00000,0x00000000ffefe010,0x00000000fff00000)
      to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
     ParOldGen       total 10240K, used 4507K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
      object space 10240K, 44% used [0x00000000fec00000,0x00000000ff066ed0,0x00000000ff600000)
     Metaspace       used 5091K, capacity 5264K, committed 5504K, reserved 1056768K
      class space    used 592K, capacity 627K, committed 640K, reserved 1048576K
    

    可以发现。新生代使用的是 Parallel Scavenge 收集器,老年代使用Parallel Old收集器

    大对象直接进入老年代

    需要大量连续空间的对象,如长字符串
    -XX:PretenureSizeThreshold 通过这个参数设置大对象的大小,超过这个值就直接在老年代分配内存。

     // -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
            byte[] allocation1,allocation2,allocation3,allocation4;
            allocation1 = new byte[2 * _1MB];
            allocation2 = new byte[2 * _1MB];
            allocation3 = new byte[2 * _1MB];
            allocation4 = new byte[4 * _1MB];
    

    打印日志

    Heap
     PSYoungGen      total 9216K, used 6709K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
      eden space 8192K, 81% used [0x00000000ff600000,0x00000000ffc8d4c0,0x00000000ffe00000)
      from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
      to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
     ParOldGen       total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
      object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000)
     Metaspace       used 5091K, capacity 5264K, committed 5504K, reserved 1056768K
      class space    used 592K, capacity 627K, committed 640K, reserved 1048576K
    

    可以看到直接在老年代分配了40%的内存

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

    虚拟机为对象设置了年龄计数器。在新生代的对象每进过一次minor gc,年龄+1,当年龄超过设置的阈值,对象会被移动到老年代。
    -XX:MTenuringThreshold 设置阈值

    动态对象年龄判定

    虚拟机并不是要求对象的年龄一定到阈值才会移动到老年代。如果在Survivior中所有年龄相同对象的大小大于survivor空间的一半,年龄大于等于该年龄的对象直接进入老年代。

    相关文章

      网友评论

          本文标题:深入理解JAVA虚拟机3-内存分配策略

          本文链接:https://www.haomeiwen.com/subject/pueubctx.html