内存分配
- 对象首先会进入Eden区。
-XX:SurvivorRatio = 8(默认值为8)
新生代:Eden+Survivor(S0)+Survivor(S1)=Xmn
-Xmn100m -XX:SurvivorRatio = 8,请问Eden区多大?
Eden:S0:S1 = SurvivorRatio:1:!
答案: 100*(8/(8+1+1)) = 80M
- 大对象会直接进入老年代
-XX:PretenureSizeThreshold=n ,如果对象的尺寸大于这个阈值,则直接进入老年代。
注意:这个参数只能在ParNew 和 Serial这两款垃圾收集器起作用。
public class TestGC {
private static final int _1MB = 1024*1024;
public static void testPretenureSizeThreshold() {
byte[] a = new byte[4*_1MB];
}
public static void main(String[] args) {
testPretenureSizeThreshold();
}
}
vm参数设置:XX:PretenureSizeThreshold 小于大对象时,分配到新生代
-Xmx20m -Xms10m -Xmn10m -XX:+PrintGCDetails -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=5145728
结果:
Heap
par new generation total 9216K, used 5260K [0x00000000fec00000, 0x00000000ff5f0000, 0x00000000ff600000)
eden space 8256K, 63% used [0x00000000fec00000, 0x00000000ff1232b0, 0x00000000ff410000)
from space 960K, 0% used [0x00000000ff410000, 0x00000000ff410000, 0x00000000ff500000)
to space 960K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff5f0000)
tenured generation total 64K, used 0K [0x00000000ff600000, 0x00000000ff610000, 0x0000000100000000)
the space 64K, 0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x00000000ff610000)
Metaspace used 2652K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 282K, capacity 386K, committed 512K, reserved 1048576K
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
vm参数设置: XX:PretenureSizeThreshold 小于大对象时,直接分配到老年代
-Xmx20m -Xms10m -Xmn10m -XX:+PrintGCDetails -XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
结果:
[GC (Allocation Failure) [Tenured: 0K->63K(64K), 0.0015259 secs] 999K->516K(9280K), [Metaspace: 2644K->2644K(1056768K)], 0.0015696 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
par new generation total 9216K, used 535K [0x00000000fec00000, 0x00000000ff5f0000, 0x00000000ff600000)
eden space 8256K, 6% used [0x00000000fec00000, 0x00000000fec85c08, 0x00000000ff410000)
from space 960K, 0% used [0x00000000ff410000, 0x00000000ff410000, 0x00000000ff500000)
to space 960K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff5f0000)
tenured generation total 4164K, used 4160K [0x00000000ff600000, 0x00000000ffa11000, 0x0000000100000000)
the space 4164K, 99% used [0x00000000ff600000, 0x00000000ffa10008, 0x00000000ffa10200, 0x00000000ffa11000)
Metaspace used 2651K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 282K, capacity 386K, committed 512K, reserved 1048576K
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
- 长期存活的对象进入老年代
-XX:MaxTenuringThreshold 一个对象经历过多少次MinorGC会进入老年代。默认值是15.
- 对象年龄的动态判断
如果在Survivor空间中相同年龄所有对象大小的综合大于Survivord空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。-XX:+PrintTenuringDistribution用于打印jvm中Age等信息。
- 空间分配担保
HandlePromotionFailure,检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次MinorGC;如果小于,或者设置不允许冒险,那这时也要改为进行一次FullGC.

5.1 在MinorGC之前,检查老年代最大可用连续空间是否大于新生代所有对象的大小。
5.2 执行MinorGC;
5.3 如果空间不够。
5.4 检查HandlePromotionFailure是否开启。
5.5 如果没有开启,这个时候执行FullGC.
5.6 如果这个参数开启,检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小。
5.7 如果大于,试着执行MinorGC.
5.8 如果小于,执行FullGC.
JVM 内存管理参数:
https://blog.csdn.net/wang379275614/article/details/78471604