0

我正在用java编写一个程序,它必须使用一个大的哈希表,哈希表越大越好(这是一个国际象棋程序:P)。基本上,作为我的哈希表的一部分,我有一个“long[]”数组、一个“short[]”数组和两个“byte[]”数组。所有这些都应该是相同的大小。但是,当我将表大小设置为一千万时,它崩溃并显示“java heap out of memory”。这对我来说毫无意义。这是我的看法:

1 Long + 1 Short + 2 Bytes = 12 bytes
x 10,000,000 = 120,000,000 bytes
/ 1024 = 117187.5 kB
/ 1024 = 114.4 Mb

现在,114 Mb 的 RAM 对我来说似乎并不算多。我的 CPU 在我的 Mac 上总共有 4Gb 的 RAM,我有一个名为 FreeMemory 的应用程序,它显示了我有多少可用的 RAM,并且在运行这个程序时它大约是 2Gb。此外,我设置了 java 首选项,如 -Xmx1024m,因此 java 应该能够使用最多内存。那么为什么不让我只分配 114Mb 呢?

4

4 回答 4

1

您预测它应该使用 114 MB,如果我运行它(在 4 GB 的 windows 盒子上)

public static void main(String... args) {
    long used1 = memoryUsed();
    int Hash_TABLE_SIZE = 10000000;
    long[] pos = new long[Hash_TABLE_SIZE];
    short[] vals = new short[Hash_TABLE_SIZE];
    byte[] depths = new byte[Hash_TABLE_SIZE];
    byte[] flags = new byte[Hash_TABLE_SIZE];
    long used2 = memoryUsed() - used1;
    System.out.printf("%,d MB used%n", used2 / 1024 / 1024);
}

private static long memoryUsed() {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

印刷

114 MB used

我怀疑您正在做其他事情,这是导致您的问题的原因。

我正在使用 Oracle HotSpot Java 7 更新 10

于 2013-01-20T21:19:41.923 回答
0

没有考虑到每个对象都是一个引用并且也使用内存,还有更多“隐藏的东西”......我们还必须考虑对齐......字节并不总是一个字节;-)

要查看实际使用了多少内存,可以使用分析器:

如果您使用标准 HashMap(或来自 JDK 的类似),每个“长”(装箱/拆箱)确实超过 8 个字节),您可以将其用作基础......(使用更少的内存)

于 2013-01-20T20:54:38.647 回答
0

根据我所读到的有关 BlueJ 的信息,几乎不可能找到严肃的技术信息,BlueJ VM 很可能根本不支持原始类型;您的数组实际上是盒装原语。BlueJ 使用所有 Java 功能的一个子集,强调面向对象。

如果是这种情况,再加上考虑到 BlueJ VM 的优先级列表中的性能和效率非常低,您实际上可能使用的内存比您想象的要多得多:整个数量级是完全可以想象的。

于 2013-01-20T21:06:05.267 回答
-2

我相信一种方法是在每次执行后清理堆内存,这里有一个链接:

Java 堆空间内存不足

于 2013-01-20T20:15:09.040 回答