根据以下文档http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html#par_gc.ergonomics.default_size使用公式 MIN(内存/4、1GB)。从公式中可以看出,但文档中仍然注明“默认的最大堆大小不会超过 1GB,无论机器上安装了多少内存”。为了验证我是否编写了以下程序
公共类分配{ 公共静态 void main(String[] args) 抛出异常 { 长兆字节 = Long.valueOf(args[0]); 长字节 = 兆字节 * 1024 * 1024; int longs = (int) (bytes / 8); long[] arr = new long[longs]; Thread.sleep(Long.MAX_VALUE); System.out.println(arr.length); } }
我在一个有 16Gb RAM 的盒子上执行了这个程序。
smeldris@us4nrsdn01 分配]$ /usr/java/jdk1.6.0_26/bin/java 分配2048 & [1] 9291 [smeldris@us4nrsdn01 分配]$ /usr/java/jdk1.6.0_26/bin/jmap -heap 9291 正在附加到进程 ID 9291,请稍候... 调试器连接成功。 检测到服务器编译器。 JVM版本是20.1-b02 使用线程局部对象分配。 8 个线程的并行 GC 堆配置: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 4208984064 (4014.0MB) 新大小 = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) 新比率 = 2 幸存者比率 = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 85983232 (82.0MB) 堆使用: PS年轻一代 伊甸空间: 容量 = 65798144 (62.75MB) 使用 = 1315976 (1.2550125122070312MB) 免费 = 64482168 (61.49498748779297MB) 2.0000199397721614% 已使用 从太空: 容量 = 10944512 (10.4375MB) 使用 = 0 (0.0MB) 免费 = 10944512 (10.4375MB) 0.0% 已使用 到太空: 容量 = 10944512 (10.4375MB) 使用 = 0 (0.0MB) 免费 = 10944512 (10.4375MB) 0.0% 已使用 PS老一代 容量 = 2322923520 (2215.3125MB) 使用 = 2147483664 (2048.000015258789MB) 免费 = 175439856 (167.31248474121094MB) 92.44745449045176% 已使用 PS烫发一代 容量 = 21757952 (20.75MB) 使用 = 2606752 (2.485992431640625MB) 免费 = 19151200 (18.264007568359375MB) 11.980686417545181% 已使用 [smeldris@us4nrsdn01 分配]$
2GB 数组是在老年代分配的。MaxHeapSize 为 4GB,是系统内存的 1/4。为什么 JVM 为堆保留 4GB?