我的一个主要项目是我修复了一些堆大小的问题。我决定尝试修复它的方式。我用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时?
答案 0 :(得分:2)
我认为其他答案忘记了重点。
代码在尝试将StringBuilder
内的原始数组复制到另一个数组(double the size from the original one)时崩溃。
在这种情况下
此时,JVM无法在新一代内存池和崩溃上安装新阵列。
答案 1 :(得分:1)
您正在追加一个2字节的UNICODE字符。你的迭代器我是600M。因此,您分配了大约1.2GB的内存。
在32位JVM上,您可以在堆上分配的理论大小为4GB。但这可能不是因为有其他因素发挥作用(交换,内核,碎片),运行的O / S占用内存,JVM占用内存,正在运行的应用占用内存,设备驱动程序,服务等。你没有得到整个4GB的理论堆(2 ^ 32)。如果我记得,如果你使用32位JVM在32位Windows上运行,那么限制大约是1.2GB标记。