2010-07-16 51 views
3

上我故意試圖引發OutOfMemoryError異常。我使用如下簡單的語句:如何使OutOfMemoryError發生在我的單元測試中的Linux JVM 64位

byte[] block = new byte[128 * 1024 * 1024 * 1024]; 

該代碼適用於帶有jdk6u21 64位的Win7 64bit。但是當我使用jdk6u21在Centos 5 64bit上運行時,即使在增大陣列的大小時也不會拋出OutOfMemoryError。

有什麼想法?

回答

3

如果你只是想消耗掉所有的內存執行以下操作:

try { 
     List<Object> tempList = new ArrayList<Object>(); 
     while (true) { 
      tempList.add(new byte[128 * 1024 * 1024 * 1024]); 
     } 
    } catch (OutOfMemoryError OME) { 
     // OK, Garbage Collector will have run now... 
    } 
+0

謝謝!這工作。 我只是將新字節[128 * 1024 * 1024 * 1024]更改爲新字節[Integer.MAX_VALUE]。 – Gilbeg 2010-08-04 06:15:05

5

Linux並不總是爲您分配所有您立即要求的內存,因爲許多實際的應用程序要求超出他們的需要。這被稱爲過度使用(這也意味着它有時候會猜測錯誤,以及可怕的OOM killer罷工)。

對於你的單元測試,我只是手動丟棄OutOfMemoryError

+0

我真的想發表一個只包含'throw new OutOfMemoryError();'但現在沒有意義的答案...... +1 – 2010-07-16 03:45:50

+0

對不起,可能是我沒有清楚。我不想簡單地扔掉OOM - 而是耗盡記憶直到乾涸。這是因爲我正在測試軟內存引用 – Gilbeg 2010-07-16 04:29:52

0

沒有OutofMemoryError的原因是內存正在分配一個未提交狀態,沒有頁面。

如果向陣列的每個4K中寫入非零字節,則會導致分配內存。

+0

爲什麼每個4K的數組? 如果我填充整個數組的字節值,如下所示,它會是一樣的嗎? 字節b = 10;數組填充(塊,b); – Gilbeg 2010-07-16 03:13:28

+0

海報假設4k塊大小(這是合理的afaik)。每4k一個字節比填充整個陣列要快。 – Slartibartfast 2010-07-16 03:35:12

1
ulimit -v 102400 
ulimit -d 102400 
unitTest.sh 

上面應該限制您的單元測試爲1M虛擬內存和1M數據段大小。當你到達其中任何一個時,你的過程應該得到ENOMEM。小心,這些限制適用於您稱之爲退出的進程/ shell;你可能想要在子shell中運行它們。

man 2 setrlimit有關如何在引擎蓋下工作的詳細信息。用於ulimit命令的help ulimit

3

128 * 1024 * 1024 * 1024 = 0,因爲int是32位。 Java不支持大於4Gb的數組。

1

你可以故意使用-Xmx標誌設置你的JVM的最大堆大小,以量小。

啓動以下程序:


public final class Test { 

    public static void main(final String[] args) { 
    final byte[] block = new byte[Integer.MAX_VALUE]; 
    } 

} 

具有以下JVM參數:-Xmx8m

這將這樣的伎倆:


Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at Test.main(Test.java:4) 
+0

謝謝 - 明白了。 – Gilbeg 2010-08-05 00:11:57

1

小點,但分配新長[Integer.MAX_VALUE的]會使內存快8倍。 (〜每個16 GB)

+0

知道了! 謝謝! – Gilbeg 2010-08-04 06:15:21