深入理解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空间的一半,年龄大于等于该年龄的对象直接进入老年代。