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

2019-11-06  本文已影响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空间的一半,年龄大于等于该年龄的对象直接进入老年代。

上一篇下一篇

猜你喜欢

热点阅读