我正在运行多线程导入,运行大约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导致了这个问题。我对么?如果是,有什么方法可以解决这个问题?
答案 0 :(得分:5)
不一定。所有这些错误意味着你几乎没有堆空间,而垃圾收集器正在放弃尝试回收空间because it has run too much without reclaiming enough space。它在代码中发生的事实并不一定意味着什么。这可能是一个完全不同的东西占用了空间,但是当它最终放弃时,那个召唤再次启动了GC。您需要进行堆转储并在YourKit或VisualVM等分析器中查看它,以查看实际情况。
答案 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);
}
}
或者,在极少数情况下,如果你真的有一个大对象要记录,让对象通过流式传输内容来记录自己,而不是创建一个压倒性的字符串。