[Q&A] -XX:PretenureSizeThreshold 作用
大于该设置值的对象直接在老年代分配,这样做的目的就是避免在Eden区及两个Survivor区之间来回复制,产生大量的内存复制操作。
样例1:
Map<Integer, byte[]> m = new HashMap<Integer, byte[]>();
for (int i = 0; i < 5 * 1024; i++) {
byte[] b = new byte[1024];
m.put(i, b);
}
-Xmx30m -Xms30m -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000
Heap
def new generation total 9216K, used 6949K [0x00000000fe200000, 0x00000000fec00000, 0x00000000fec00000)
eden space 8192K, 84% used [0x00000000fe200000, 0x00000000fe8c96f0, 0x00000000fea00000)
from space 1024K, 0% used [0x00000000fea00000, 0x00000000fea00000, 0x00000000feb00000)
to space 1024K, 0% used [0x00000000feb00000, 0x00000000feb00000, 0x00000000fec00000)
tenured generation total 20480K, used 0K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
the space 20480K, 0% used [0x00000000fec00000, 0x00000000fec00000, 0x00000000fec00200, 0x0000000100000000)
Metaspace used 2794K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 298K, capacity 386K, committed 512K, reserved 1048576K
[Q&A] 发现 5M
空间还是在新生代没分配到老年代
原因是,虚拟机面对体量不大的对象,会优先分配到TLAB区域中,因此失去了分配到老年代的机会。
下面禁用TLAB重试,发现老年代会直接新增5M
的使用量。
-Xmx30m -Xms30m -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB
Heap
def new generation total 9216K, used 995K [0x00000000fe200000, 0x00000000fec00000, 0x00000000fec00000)
eden space 8192K, 12% used [0x00000000fe200000, 0x00000000fe2f8f50, 0x00000000fea00000)
from space 1024K, 0% used [0x00000000fea00000, 0x00000000fea00000, 0x00000000feb00000)
to space 1024K, 0% used [0x00000000feb00000, 0x00000000feb00000, 0x00000000fec00000)
tenured generation total 20480K, used 5473K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
the space 20480K, 26% used [0x00000000fec00000, 0x00000000ff158460, 0x00000000ff158600, 0x0000000100000000)
Metaspace used 2794K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 298K, capacity 386K, committed 512K, reserved 1048576K