toStringBuilder导致问题

时间:2013-02-26 05:04:55

标签: java apache-commons

我正在运行多线程导入,运行大约1-2个小时。  并在导入之前,将数据放入表中。 我正在检查

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

其中MyObject使用ToStringBuilder方法中的toString

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导致了这个问题。我对么?如果是,有什么方法可以解决这个问题?

2 个答案:

答案 0 :(得分:5)

不一定。所有这些错误意味着你几乎没有堆空间,而垃圾收集器正在放弃尝试回收空间because it has run too much without reclaiming enough space。它在代码中发生的事实并不一定意味着什么。这可能是一个完全不同的东西占用了空间,但是当它最终放弃时,那个召唤再次启动了GC。您需要进行堆转储并在YourKitVisualVM等分析器中查看它,以查看实际情况。

答案 1 :(得分: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);
   }
}

或者,在极少数情况下,如果你真的有一个大对象要记录,让对象通过流式传输内容来记录自己,而不是创建一个压倒性的字符串。