尽管有足够的可用内存,但巨大的数组会抛出内存不足 [英] Huge arrays throws out of memory despite enough memory available

查看:39
本文介绍了尽管有足够的可用内存,但巨大的数组会抛出内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 -Xmx1G 标志提供 1 GB 的堆,以下按预期工作:

Using the -Xmx1G flag to provide a heap of one gigabyte, the following works as expected:

public class Biggy {
    public static void main(String[] args) {
        int[] array = new int[150 * 1000 * 1000];
    }
}

该数组应表示大约 600 MB.

The array should represent around 600 MB.

然而,以下抛出 OutOfMemoryError:

However, the following throws OutOfMemoryError:

public class Biggy {
    public static void main(String[] args) {
        int[] array = new int[200 * 1000 * 1000];
    }
}

尽管数组应该表示大约 800 MB,因此很容易放入内存中.

Despite the array should represent around 800 MB and therefore easily fit in memory.

丢失的记忆去哪儿了?

推荐答案

在 Java 中,堆中通常有多个区域(和子区域).你有一个年轻且终身的地区,拥有最多的收藏家.大数组会立即添加到永久区域,但是根据您的最大内存大小,将为年轻空间保留一些空间.如果您缓慢分配内存,这些区域将调整大小,但是如您所见,像这样的大块可能会失败.

In Java you typically have multiple regions (and sub regions) in the heap. You have a young and tenured region with most collectors. Large arrays are added to the tenured area straight away however based on your maximum memory size, some space will be reserved for the young space. If you allocate memory slowly these regions will resize however a large block like this can simply fail as you have seen.

鉴于内存通常相对便宜(并非总是如此),我只会将最大值增加到您希望应用程序使用过多时失败的程度.

Given memory is usually relatively cheap (not always the case) I would just increase the maximum to the point where you would want the application fail if it ever used that much.

顺便说一句:如果您有这样的大型结构,您可以考虑使用直接内存.

BTW: If you have a large structure like this you might consider using direct memory.

IntBuffer array = ByteBuffer.allocateDirect(200*1000*1000*4)
                            .order(ByteOrder.nativeOrder()).asIntBuffer();

int a = array.get(n);
array.put(n, a+1);

写起来有点乏味,但有一个很大的优势,它几乎不使用堆.(开销小于 1 KB)

Its a bit tedious to write but has one big advantage, it uses almost no heap. (there is less than 1 KB over head)

这篇关于尽管有足够的可用内存,但巨大的数组会抛出内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆