使用 -Xmx1G
标志来提供 1 GB 的堆,以下内容按预期工作:
public class Biggy {
public static void main(String[] args) {
int[] array = new int[150 * 1000 * 1000];
}
}
数组应该代表大约 600 MB。
但是,以下会抛出 OutOfMemoryError:
public class Biggy {
public static void main(String[] args) {
int[] array = new int[200 * 1000 * 1000];
}
}
尽管数组应该表示大约 800 MB,因此很容易放入内存中。
丢失的内存去哪儿了?
最佳答案
在 Java 中,堆中通常有多个区域(和子区域)。你有一个年轻而老牌的地区, Collection 家最多。大型数组会立即添加到永久区域,但是根据您的最大内存大小,将为年轻空间保留一些空间。如果您缓慢地分配内存,这些区域会调整大小,但是像这样的大块可能会像您所见的那样简单地失败。
鉴于内存通常相对便宜(并非总是如此),我只会将最大值增加到您希望应用程序在使用那么多时失败的程度。
顺便说一句:如果您有这样的大型结构,您可能会考虑使用直接内存。
IntBuffer array = ByteBuffer.allocateDirect(200*1000*1000*4)
.order(ByteOrder.nativeOrder()).asIntBuffer();
int a = array.get(n);
array.put(n, a+1);
写起来有点乏味,但有一个很大的优势,它几乎不使用堆。 (超过 1 KB)
关于java - 尽管有足够的可用内存,但巨大的数组仍会耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7298455/