Java堆小于预期

时间:2015-02-15 07:39:53

标签: java memory

我的一个主要项目是我修复了一些堆大小的问题。我决定尝试修复它的方式。我用java -jar <jarfile> -Xmx5G -Xms4G运行了以下内容。 (初始4GB,最大5GB)。

int i = 0;

try {
    StringBuilder sb = new StringBuilder();

    for(i = 0; i < Integer.MAX_VALUE; i++) {
        sb.append('0');
    }
} catch (OutOfMemoryError e) {
    System.out.println("At: " + i);
    e.printStackTrace();
}

哪个印刷

At: 603979774
java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)

为什么我的堆访问限制为2个字节,短于576mb,当它设置为至少4gb时?

2 个答案:

答案 0 :(得分:2)

我认为其他答案忘记了重点。

代码在尝试将StringBuilder内的原始数组复制到另一个数组(double the size from the original one)时崩溃。

在这种情况下

  1. 原始阵列的大小~1.2GB
  2. 新阵列的大小~2.4GB
  3. 此时,JVM无法在新一代内存池和崩溃上安装新阵列。

答案 1 :(得分:1)

您正在追加一个2字节的UNICODE字符。你的迭代器我是600M。因此,您分配了大约1.2GB的内存。

在32位JVM上,您可以在堆上分配的理论大小为4GB。但这可能不是因为有其他因素发挥作用(交换,内核,碎片),运行的O / S占用内存,JVM占用内存,正在运行的应用占用内存,设备驱动程序,服务等。你没有得到整个4GB的理论堆(2 ^ 32)。如果我记得,如果你使用32位JVM在32位Windows上运行,那么限制大约是1.2GB标记。