8

我正在做一个小任务,我需要在一个数组中存储大约 10 亿个整数。但是,我遇到了堆空间问题。你能帮我解决这个问题吗?

机器详细信息:Core 2 Duo 处理器,4 GB RAM。我什至尝试过 -Xmx 3072m 。有什么解决方法吗? 同样的事情在 C++ 中也有效,所以绝对应该有一种方法可以将这么多的数字存储在内存中。

下面是我得到的代码和异常:

public class test {
    private static int C[] = new int[10000*10000];

    public static void main(String[] args) {
        System.out.println(java.lang.Runtime.getRuntime().maxMemory()); 

    }

}

异常:线程“主”java.lang.OutOfMemoryError 中的异常:测试时的 Java 堆空间。(test.java:3)

4

5 回答 5

4

使用关联数组。键是整数,值是计数(整数被添加到列表中的次数)。

如果分布相对随机,这应该可以为您节省一些可观的空间,如果不是,则更是如此。

于 2013-02-02T21:20:08.220 回答
3

如果您需要存储 10 亿个完全随机的整数,那么恐怕您确实需要相应的空间,即大约 4GB 的内存用于 32 位int数字。您可以尝试增加 JVM 堆空间,但您需要有 64 位操作系统和至少一样多的物理内存——而且您只能做到这一点。

另一方面,如果您可以利用应用程序中的特定约束,您可能能够更有效地存储这些数字。

例如,如果您只需要知道一个特定元素int是否包含在一个集合中,那么您可以使用一个位集合——即int范围内的每个值一个位。这大约是 40 亿位,即 512 MB - 一个更合理的空间需求。例如,少数BitSet对象可以覆盖整个 32 位整数范围,而无需编写任何位处理代码......

于 2013-02-02T21:08:05.987 回答
2

可能使用内存映射文件会有所帮助吗?它们不是从堆中分配的。这是一篇如何创建矩阵的文章。数组应该更容易。

将内存映射文件用于巨大的矩阵 - Peter Lawrey

于 2013-02-02T22:31:34.230 回答
0

您可以在 32 位系统上增加到 4GB。如果您使用的是 64 位系统,则可以更高。

输入 cmd 这个

java -Xmx4g programname
于 2013-02-02T21:08:22.567 回答
0

由于这么大的阵列可能不适合您的 RAM,因此您需要配置足够的 HDD 交换空间。4 - 16 Gb 交换在这些时候看起来并不现实。

Java 只允许int用作数组的索引,而不是long. 因此,最大可能的数组可以有 2147483648 个值,足够了。

用于-Xmx提高默认情况下可能不足的内存上限。3072m 是不够的,因为 10 亿个整数需要大约 4 Gb。由于操作系统等也需要空间,因此具有 4 Gb RAM 的机器无法在内存中保存所有 4 Gb 数据结构。

JRE 或 OS 也可能拒绝一次性授予这么大的一块内存,需要分配一些较小的块(可能是数组或数组)。

于 2013-02-02T21:13:42.987 回答