2012-11-01 185 views
0

我有一個關於Java堆空間的問題。Java堆內存

我有一個程序使用地理工具從街道網絡創建圖形。 我做了一些東西,但我遇到了OutOfMemoryError,但我不確定爲什麼。我使用下面的代碼來獲得可用內存量。

Runtime rt = Runtime.getRuntime(); 
long maxMb = rt.freeMemory()/(1024*1024); 
System.out.println("Your JVM has " + maxMb + " MB of memory left"); 

而當我運行我的程序時,似乎有足夠的內存(請參閱輸出)。此控制檯輸出在發生OutOfMemory錯誤之前完成。那麼到底發生了什麼問題?當我放大Java堆空間時,發生OutOfMemory錯誤(但剩餘1461 MB)。我不知道爲什麼會發生這種情況?有任何想法嗎?

Your JVM has 981 MB of memory left 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOf(Unknown Source) 
at java.util.Arrays.copyOf(Unknown Source) 
at java.util.ArrayList.grow(Unknown Source) 
at java.util.ArrayList.ensureCapacityInternal(Unknown Source) 
at java.util.ArrayList.add(Unknown Source) 
at masterthesis.datastructures.Stroke.addStrokeSegment(Stroke.java:78) 
at masterthesis.algorithms.StrokeBuilder.buildStroke(StrokeBuilder.java:145) 
at org.geotools.test.Main.main(Main.java:109) 
+0

五月有一些內存泄漏(或)正在加載的圖像比繳費堆大? – kosa

+0

這個程序比您給出的兩行更多嗎? –

+0

這是一個相當大的計劃。但主要部分是它有一個包含800條街道(線條字符串)的shapefile的街道網絡。我所做的就是用geotools中的圖形構建器創建一個圖形,然後遍歷所有節點並構建所謂的筆畫(=具有小偏轉角度的線條集合)。在此期間發生錯誤。 – user1765902

回答

0

由於輸出表明您數組列表生長過程中有很多的記憶中留下和錯誤ocurrs我的猜測是,你有你把對象。一個真正巨大的ArrayList當JVM試種列表中沒有足夠的堆空間來容納列表的大小加倍。

我會調查您實際上在addStrokeSegment()的列表中放入了多少個對象。

+0

我認爲就是這樣。當我在插入前檢查大小時,即使它不應該是巨大的。我會試圖找出錯誤,但如果我無法,我會回來;) – user1765902

+0

發現錯誤。這是一個非常令人討厭的無限循環,它繼續調用addStrokeSegment()方法來生成一個巨大的數組列表。再次感謝!問題已解決 – user1765902

0

您應該使用jmap來了解您的記憶充滿了什麼。

0

嘗試閱讀Java: OutOfMemoryError Exception and freeMemory()

Runtime.freeMemory()的javadoc說,這是返回「近似的內存目前可用於未來分配的對象總量」

的方式,所有的動態結構工作他們分塊分配內存。當HashMap變滿時,它不會爲多一個對象分配額外的空間。它分配一些大小的塊。我不知道它在JVM中的確切工作方式,但它可能會嘗試分配兩倍於當前使用的內存量。

1

以下是調試OOM的一種方法。

  1. 將您的最大堆大小調整爲合理的大小,例如256 MB。保持合理的低點將在第3步中幫助你。
  2. 將-XX:+ HeapDumpOnOutOfMemoryError添加到命令行中。這會在遇到OOM後轉儲內存。
  3. 打開Eclipse Memory Analyzer的轉儲並嘗試分析最大的對象。它可以生成看起來這樣的報告。

enter image description here

+0

感謝您的回答。我會看看 – user1765902