我在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?
答案 0 :(得分: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 update 10
答案 1 :(得分:0)
没有考虑到每个对象都是一个引用并且还使用了内存,而且更多的是“隐藏的东西”......我们还必须考虑到对齐...字节并不总是一个字节; - )< / p>
要查看实际使用的内存量,可以使用分析器:
如果你使用标准的HashMap(或类似的JDK),每个“long”(装箱/拆箱)确实超过8字节),你可以用它作为基础...(使用更少的内存)
答案 2 :(得分:0)
根据我对BlueJ的了解,并且几乎不可能找到严肃的技术信息,BlueJ VM很可能根本不支持原始类型;你的数组实际上是盒装基元。 BlueJ使用所有Java功能的子集,重点是面向对象。
如果是这种情况,另外考虑到BlueJ VM的优先级列表中的性能和效率相当低,您实际上可能会使用比您想象的更多的内存:整个数量级是可以想象的。
答案 3 :(得分:-2)
我相信在每次执行后清理堆内存的方法有一种方法: