2011-05-21 48 views
1

我嘗試創建一個Integer數組(我用自己的對象嘗試過,但int也是一樣),大小爲3000萬。我不斷收到 「的OutOfMemoryError:Java堆空間」int []和Integer []數組的內存佔用空間

Integer [] index = new Integer[30000000]; 
for (int i = 0 ; i < 30000000 ; i++){ 
    index[i] = i; 
} 

我檢查了總堆空間,使用和 「maxMemory()」 ,看到我開始64 「調用Runtime.getRuntime()totalMemory()。」 MB和最大900 + MB,並在運行期間,我達到900+在堆和粉碎。

現在我知道整數需要4個字節,所以即使我乘以30 * 4 * 1000000我應該仍然只能得到大約150-100兆。

如果我嘗試一個原始類型,如int,它的工作原理。

我該如何解決它?

+0

以更多堆內存運行程序。 – 2011-05-21 13:16:22

回答

6

Java的int原語佔用4個字節,但如果使用像Integer這樣的ValueObject,它將佔用更多的空間。根據你的機器,單獨一個引用可能佔用32或64位+它正在包裝的原始大小。

如果空間有問題,您應該使用原始整數。 Here is a very good SO answer that explains this topic in more detail

+0

我相信他對Integer的使用僅僅是爲了演示的目的。我相信真正的代碼使用非整數自定義類對象的數組。 – 2011-05-21 13:22:15

+0

你是對的,我用我自己的物體。我不明白它如何可以佔用這麼多的空間 – Ben2307 2011-05-22 08:36:52

+0

是的,這是參考大小的開銷,讓你。如果您使用的是Java 64位,您還可以使用-XX:+ UseCompressedOops來幫助減少引用的大小。 – 2011-05-22 14:50:08

0

Integer是一個超過4個字節的對象。依賴於實施還有多少。你真的需要Integer嗎?唯一的好處是它可以是null。也許你可以用一個「基本價值」來代替;說,-1,或Integer.MIN_VALUE

0

也許你應該使用數據庫而不是巨大的數組,但是如果你必須使用大量的對象,你是否嘗試過在運行Java應用程序時使用-Xms命令行參數來增加Java內存大小發射?

2

讓我們假設我們正在談論最近的32位Sun JVM。

  • 每個Integer對象有1個int字段 - 佔用4個字節。
  • 每個Integer對象都有2個標題字 - 佔用8個字節。
  • 分配的粒度是(我相信)2個字 - 4個字節的填充。
  • Integer []對每個數組元素/位置有4個字節的引用。

所以總數爲每個數組元素20個字節。 20 x 30 x 1,000,000 = 600,000,000 Mbytes。現在添加這樣一個事實,即世代收集器將分配至少3個不同大小的對象空間,並且可以輕鬆地添加高達900+兆字節。

how could i fix it ?

  • 使用int[]而不是Integer
  • 如果Integer值主要代表-128至+127範圍內的數字,請將其分配爲Integer.valueOf(int)。 JLS保證以這種方式創建的Integer對象將被共享。 (請注意,當通過自動裝箱創建Integer時,JLS規定使用valueOf。因此,實際上,此「修復」已在您的示例中應用。)
  • 如果您的Integer值大多來自較大但仍然很小的域,請考慮實施您自己的緩存以共享Integer對象。

My question was about Integer as an example, in my program i use my own object that only holds an array of bytes (max size of 4). when i create it, it takes a lot more then 4 bytes on the memory.

是的,它會做。

讓我們假設你的類是這樣定義的:

public class MyInt { 
    private byte[] bytes = new byte[4]; 
    ... 
} 

每個MyInt將佔據:

  • MyInt頭的話 - 8個字節
  • MyInt.bytes場 - 4字節
  • 填充 - 4字節
  • 標題w ORDS爲字節數組 - 12個字節
  • 陣列內容 - 4個字節

現在添加由MyInt參考所佔用的空間:

  • 參照每個MyInt - 4個字節

總共 - 36個字節/ MyInt元素的一個MyInt[]

相比之下,與每一個每int[]int元件的Integer[]或4字節Integer元件20個字節。

+0

我的問題是關於整數作爲例子,在我的程序中我使用我自己的對象,只保存一個字節數組(最大大小爲4)。 當我創建它時,它會佔用內存上多於4個字節的空間。 – Ben2307 2011-05-22 08:24:42

0

這不是你正在尋找的,但最佳的解決方案是在這個簡單的例子中使用函數而不是數組。

static int index(int num) { 
    return num; 
} 

如果你有一個更現實的例子,你可以使用其他優化。