2013-01-20 45 views
0

我正在用java編寫一個程序,它必須利用一個大的散列表,散列表可以越大越好(這是一個國際象棋程序:P)。基本上,作爲我的散列表的一部分,我有一個「long []」數組,「short []」數組和兩個「byte []」數組。所有這些都應該是相同的大小。但是,當我將表格大小設置爲一千萬時,它崩潰並顯示「java堆內存不足」。這對我來說沒有意義。以下是我的看法:在Java中使用太多的Ram

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的應用程序,它顯示了我有多少內存可用,運行該程序時它的容量是2Gb左右。另外,我設置了像-Xmx1024m這樣的java選項,所以java應該可以使用多達一個內存。那爲什麼它不讓我分配114Mb?

+2

您可以使用內存分析器查看究竟發生了什麼。 – NPE

+0

你可以嘗試較小的尺寸?排除它可能是一些很棒的遞歸。 –

+2

你能想出一個你認爲佔用太多空間的最小自包含的例子,並將它與你正在使用的確切'java'命令行一起發佈嗎? – NPE

回答

0

一直沒有考慮到每個對象是一個參考,還可以使用內存,更多「隱藏的東西」 ......我們還必須考慮到也對齊......字節並不總是一個字節;-)

,看看有多少內存真的在使用中,你可以使用一個分析器:如果您使用的是標準的HashMap(或JDK類似)

,每個「長「(拳擊/拆箱)真的超過8bytes),你可以使用這個作爲基地...(使用更少的內存)

0

從我所讀到的關於BlueJ以及嚴重的技術信息幾乎是不可能發現的,BlueJ VM很可能根本不支持原始類型;你的數組實際上是裝箱的基元。 BlueJ使用所有Java功能的子集,重點在於面向對象。

如果是這樣的話,再加上考慮到BlueJ虛擬機的優先級列表中的性能和效率相當低,您可能實際上使用的存儲容量比您想象的要多得多:整個數量級是相當可想象的。

1

你預測它應該使用114 MB,如果我運行這個(在Windows中有4 GB)

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

+0

......就像使用BlueJ而不是真正的JVM一樣。 –

+0

@MattBall我不認爲我需要提供使用的JVM,但我懷疑你是對的。 –

+0

上半個小時我一直忙於研究BlueJ,它的功能集似乎指向構建在JVM之上的JVM。 BlueJ是用Java編寫的,但提供了許多類似動態語言的交互功能,並且無法在使用生產虛擬機的專業IDE中進行復制。 –