繁体   English   中英

在Java中使用过多的Ram

[英]Using too much Ram in Java

我正在用Java写一个程序,该程序必须利用一个大的哈希表,哈希表可以越大越好(这是一个国际象棋程序:P)。 基本上,作为哈希表的一部分,我有一个数组“ long []”,一个数组“ short []”和两个数组“ byte []”。 它们的大小均应相同。 但是,当我将表大小设置为1000万时,它崩溃并显示“ java堆内存不足”。 这对我来说毫无意义。 这是我的看法:

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的内存似乎并不多。 总的来说,我的CPU在Mac上具有4Gb的RAM,我有一个名为FreeMemory的应用程序,它显示我有多少RAM可用,运行此程序时大约有2Gb。 另外,我设置了-Xmx1024m之类的java首选项,因此java应该能够使用最多的内存。 那为什么不让我只分配114Mb呢?

您预测它应该使用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

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

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

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

根据我对BlueJ的了解,几乎无法找到重要的技术信息,BlueJ VM很可能根本不支持原始类型。 您的数组实际上是盒装基元的。 BlueJ使用所有Java功能的一个子集 ,重点是面向对象。

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

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

Java堆空间不足

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM