2017-04-07 83 views
6

我試圖用Java創建二維數組如下:最大限度

int[][] adjecancy = new int[96295][96295]; 

,但它與下面的錯誤而失敗:

JVMDUMP039I Processing dump event "systhrow", detail "java/lang/OutOfMemoryError" at 2017/04/07 11:58:55 - please wait. 
JVMDUMP032I JVM requested System dump using 'C:\eclipse\workspaces\TryJavaProj\core.20170407.115855.7840.0001.dmp' in response to an event 
JVMDUMP010I System dump written to C:\eclipse\workspaces\TryJavaProj\core.20170407.115855.7840.0001.dmp 
JVMDUMP032I JVM requested Heap dump using 'C:\eclipse\workspaces\TryJavaProj\heapdump.20170407.115855.7840.0002.phd' in response to an event 
JVMDUMP010I Heap dump written to C:\eclipse\workspaces\TryJavaProj\heapdump.20170407.115855.7840.0002.phd 

來解決,這是通過一種方法增加JVM內存,但我試圖提交在線編碼挑戰的代碼。在那裏它也失敗了,我將無法改變那裏的設置。

是否有任何標準限制或指導創建大型數組不應該超過?

+2

是否必須是2D數組? – stholzm

+3

您正在嘗試分配37GB的內存。這是相當多的,即使增加JVM內存也需要一臺大型機器。你需要找到一個更聰明的算法(這就是爲什麼它被稱爲編碼挑戰) – Henry

+1

你問是否有可能不使用40GB的內存分配40GB的內存?不,這不對。如果您告訴我們*爲什麼*您正在嘗試這樣做,也許我們可以幫助改善您的解決方案。 – shmosel

回答

13
int[][] adjecancy = new int[96295][96295]; 

當你做,你正在試圖分配96525*96525*32位這是近37091 MB這是近37演出。單獨爲Java獲取PC的內存是不可能的。

我不認爲你的程序初始化時需要手頭那麼多的數據。可能你必須看看ArrayList,它給你大小的動態分配,然後在運行時保持釋放是一個考慮的關鍵。

創建數組沒有限制或限制。只要你有記憶,你可以使用它。但請記住,您不應該持有一塊使JVM生活忙碌的內存。

+0

我的計算不好 - 更正了。 –

0

它取決於可用於JVM的最大內存和陣列的內容類型。對於int,我們有4個字節的內存。現在,如果機器上有1 MB內存可用,則最多可以容納1024 * 256個整數(1 MB = 1024 * 1024字節)。牢記這一點,你可以相應地創建你的二維數組。

1

建議分配可以分配的最大堆大小是機器RAM大小的1/4。

1在Java中的int需要4個字節,您的數組分配需要大約37.09GB的內存。

在這種情況下,即使我假設你正在爲陣列分配Full Heap,你的機器應該在148GB RAM左右。這是巨大的。

看看下面。

編號:http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gc-ergonomics.html

希望這有助於。

0

您可以創建的數組取決於JVM堆大小。

96295 * 96295 * 4(每個字節的字節數)= 37,090,908,100字節=〜34.54GB字節。競爭性代碼評判者中的大多數JVM都沒有那麼多的內存。因此錯誤。

想了解一下數組大小可以用給定堆大小是一個好主意 - 運行該代碼段有不同的-Xmx設置:

Scanner scanner = new Scanner(System.in); 
    while(true){ 
     System.out.println("Enter 2-D array of size: "); 
     size = scanner.nextInt(); 

     int [][]numbers = new int[size][size]; 
     numbers = null; 
    } 

例如使用-Xmx 512M - > 2k個〜10k +元素的數組。

一般來說,在評估提交時,大多數在線評委有〜1.5-2GB堆

+0

@亨利 - 感謝您糾正錯誤。 –

3

數組顯然必須適合內存。如果沒有,典型的解決方案是:

  • 您真的需要int(最大值2,147,483,647)嗎?也許byte(最大 值127)或short是否足夠好? byteint小8倍。
  • 你在數組中有很多相同的值嗎(比如零)?嘗試使用稀疏數組。

例如:

Map<Integer, Map<Integer, Integer>> map = new HashMap<>(); 
map.put(27, new HashMap<Integer, Integer>()); // row 27 exists 
map.get(27).put(54, 1); // row 27, column 54 has value 1. 

他們需要每儲值更多的內存,但有基本的陣列空間沒有限制(可以使用龍,而不是整數作爲索引,使他們真正巨大的)。

  • 也許你只是不知道數組應該是多長?嘗試ArrayList,它會自動調整大小。對於2D陣列使用ArrayListsArrayList

  • 如果沒有其他幫助,請使用RandomAccessFile將過度生長的數據存儲到文件系統中。在一個好的工作站上,100 Gb或者大約在這些時間不是問題,您只需計算文件中所需的偏移量即可。文件系統顯然比RAM慢得多,但是SSD驅動器可能是可以忍受的。

+1

我喜歡這個答案很多,因爲它不僅說明了明顯,而且概述了多種可能的解決方案,而不會破壞挑戰。這個挑戰可能有一個技巧,就像一個稀疏矩陣的更高效的內存表示。 – stholzm