2013-02-26 124 views
2

我正在運行一個運行約1-2小時的多線程導入。 並在導入數據之前將數據放入表格中。 我檢查toStringBuilder導致問題

if(debug.isEnabled()) 
logger.debug("Object="+MyObject); 

其中MyObjecttoString方法使用ToStringBuilder

java.lang.OutOfMemoryError: GC overhead limit exceeded 
     at java.util.Arrays.copyOfRange(Arrays.java:2694) 
     at java.lang.String.<init>(String.java:203) 
     at java.lang.StringBuffer.toString(StringBuffer.java:561) 
     at org.apache.commons.lang3.builder.ToStringBuilder.toString(ToStringBuilder.java:1063) 

我在想,toStringBuilder是造成這個問題。我對麼?如果是,有什麼方法可以解決這個問題?

回答

5

不一定。所有這些錯誤意味着你幾乎已經沒有堆空間了,垃圾回收器正在放棄嘗試回收空間because it has run too much without reclaiming enough space。它在代碼中發生的事實並不一定意味着什麼。這可能是完全不同的東西在這個空間裏吃了東西,但是這個電話又一次開啓了GC,最終放棄了。你需要把堆轉儲,並在YourKitVisualVM這樣的分析器中查看它,看看實際發生了什麼。

0

您的對象在內存中構造了一個太大的字符串,可能在toStringBuilder()方法中。

爲了避免這種情況,儘量不要進口爲每行到你的數據庫像

if (debug.isEnabled()) { 

    // since you are importing rows it must be a collection/array 
    logger.debug("Object="); 
    for(Row r in MyObject.getRows()) { 
     logger.debug(r); 
    } 
} 

,或在極少數情況下,如果你真的有一個大的對象進行登錄,具有對象通過流媒體內容登錄自己登錄,而不是創建一個壓倒性的字符串。