2016-02-25 43 views
6

我有,我將使用一個非常大的short[]陣列方案更大的堆空間:Java要求比什麼是合理的

import java.lang.Math; 

public class HPTest { 

    public static void main(String[] args) { 
     int n = 30; 
     short[] a = new short[(int)Math.pow(2,n)]; 
    } 
} 

據我所知,short[]陣列應每元素中使用2個字節,因此具有2^30元素的數組應該需要大約2吉比的RAM。

爲了運行程序,因此,我試圖

java -Xms2000m HPTest 

,但仍然得到了堆空間錯誤。即使在3000m我也得到了同樣的錯誤,但在4000m它工作。

任何想法,爲什麼我必須遠遠高於2000m的估計限制?

編輯: 正如許多用戶指出的那樣,我在聲明short需要1個字節而不是2個字節時犯了一個非常尷尬的錯誤。那麼問題應該是爲什麼它不能滿足2000m

+7

短是2個字節... –

+1

一個'byte'是一個字節,因此名字。順便說一句'1 << n'是計算2的冪的更有效的方法。 –

+0

即使如此,3000m/3gb應該足夠他嗎? –

回答

5

這麼大的東西,在堆外面會更加快樂。你最好查找NIO並使用直接字節緩衝區來備份大型短陣列。這個內存可以放在堆外,遠離垃圾收集器(可能有時候感覺傾向於將緩衝區從一個區域複製到另一個區域)。

請參閱java.nio.ShortBuffer並開始從那裏挖掘。

+0

謝謝!第二個想法,我可能能夠切換到一個字節數組。無論如何,我將基本上使用數組作爲與0到2^30-1的所有整數的不同容器對應的標誌數組。因此,當我遍歷這些整數時,我將把我的短/字節數組的相應索引處的標誌設置爲某個值。就我所見,我可以通過每次在緩衝區調用put()來完成此操作。這會很慢嗎? –

+0

實際上,這個大的分配直接進入「老一代」池,並且不會被垃圾收集器複製。我只是憑經驗測試這是真實的,我似乎記得在某個地方閱讀,但我目前沒有參考。 – Andreas

+0

@AlexandreVandermonde如果他們只是標誌,你應該把它設置爲一個布爾數組,並且JVM可以將8個布爾變成一個字節。 – Andreas