以下代码在运行jdk1.6.0_14的Linux 3.5企业版框中抛出OutofMemoryError,但在JDK 1.6.0_20上运行正常我无言以对,它发生了。超过GCOverhead限制
while (rs.next()) {
for (TableMetaData tabMeta : metaList) {
rec.append(getFormattedString(rs, tabMeta));
}
rec.append(lf);
recCount++;
if (recCount % maxRecBeforWrite == 0) {
bOutStream.write(rec.toString().getBytes());
rec = null;
rec = new StringBuilder();
}
}
bOutStream.write(rec.toString().getBytes());
的getFormattedString()方法放在这里:
private String getFormattedString(ResultSet rs, TableMetaData tabMeta)
throws SQLException, IOException {
String colValue = null;
// check if it is a CLOB column
if (tabMeta.isCLOB()) {
// Column is a CLOB, so fetch it and retrieve first clobLimit chars.
colValue = String.format("%-" + clobLimit + "s", getCLOBString(rs,
tabMeta));
} else {
colValue = String.format("%-" + tabMeta.getColumnSize() + "s", rs
.getString(tabMeta.getColumnName()));
}
return colValue;
}
下面是异常跟踪:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Formatter$FormatSpecifier.justify(Formatter.java:2827)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2821)
at java.util.Formatter$FormatSpecifier.printString(Formatter.java:2794)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2677)
at java.util.Formatter.format(Formatter.java:2433)
at java.util.Formatter.format(Formatter.java:2367)
at java.lang.String.format(String.java:2769)
at com.boa.cpal.cpal2repnet.main.CPALToReportNet.getFormattedString(Unknown Source)
我怀疑是使用的String.format的是罪魁祸首,但不当然。如何解决这个问题?
请注意,此代码已被写入查询数据库中有巨大的表来读取结果集并创建具有特定格式的提取文件。
我怀疑在两个JVM上通过Xmx分配给堆的内存是不同的?或者JDK 1.6_20以-XX启动:-UseGCOverheadLimit? – JoseK 2010-08-24 05:56:21
实际上在Windows上分配的内存仅为512M,而在Linux上则为1024M。不,Windows上的JDK不是以-XX开头的:-UseGCOverheadLimit选项。 – Amit 2010-08-24 07:29:57
就我个人而言,我不会在循环中抛弃'StringBuilder',而只需通过调用['setLength(0)']来清除它(http://download.oracle.com/javase/6/docs/api/java /lang/StringBuilder.html#setLength(int))这种方式缓冲区不需要每次重新分配。频繁的分配和解除分配是“GCOverhead Limit exceeded”问题的共同目标。 – 2010-08-24 07:46:25