创建大量XML时出现内存不足错误

时间:2009-12-01 07:21:50

标签: java xml memory-management

引起:java.lang.OutOfMemoryError:Java堆空间      at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)      at java.lang.AbstractStringBuilder.append(Unknown Source)      在java.lang.StringBuffer.append(未知来源)      at java.io.StringWriter.write(Unknown Source)      在com.ctc.wstx.sw.BufferingXmlWriter.flushBuffer(BufferingXmlWriter.java:1358)      在com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:224)      在com.ctc.wstx.sw.BufferingXmlWriter.close(BufferingXmlWriter.java:198)      在com.ctc.wstx.sw.BaseStreamWriter._finishDocument(BaseStreamWriter.java:1429)      在com.ctc.wstx.sw.BaseStreamWriter.close(BaseStreamWriter.java:264)      在org.codehaus.stax2.ri.Stax2EventWriterImpl.close(Stax2EventWriterImpl.java:178)      at org.utils.JcoFunctionToXmlTransformer.transform(JcoFunctionToXmlTransformer.java:163

目标 - 将SAP以JcoTable形式返回的数据转换为XML 问题 - java.lang.OutOfMemoryError:Java堆空间。

当数据非常庞大时,如果行数超过25,000,则会出现上述错误 我们面临同样的问题,即使在使用Jco API方法转换为XML并使用外部自定义代码(使用Stax API)逐节点读取和流式传输为XML时也是如此

6 个答案:

答案 0 :(得分:9)

您可以通过以下方式增加JVM的内存限制:

java -Xmx512m ...

java -Xmx1024m ...

或您需要的任何尺寸。

请注意,您可能需要修改算法,例如,将XML直接序列化为OutputStream,而不是先构建一个庞大的内存结构,然后将 序列化为OutputStream。 (这完全取决于代码正在做什么的细节。)

今年早些时候,我遇到了类似的情况,我将XML生成为StringBuffer,然后将StringBuffer写入HTTP响应OutputStream。这工作正常,直到有人要求200Mb的XML!我很快改变了代码,直接生成XML到OutputStream,不仅节省了内存,还节省了CPU。

答案 1 :(得分:6)

如果你需要解析大的XML文件(并且添加到Java堆并不总是有效),你需要一个SAX解析器,它允许你解析XML流而不是将整个DOM树加载到内存中。

答案 2 :(得分:2)

你是否经常使用大字符串的子串?

用jvisualvm附上,看看你的记忆在哪里。

答案 3 :(得分:1)

在运行应用程序时,您是否增加了Java上的VM选项?例如:

java -Xmx1024m ...

给它一个千兆字节的堆空间。

如果这是在应用程序服务器或Web容器中,您通常会在配置文件或启动脚本中找到这些选项。

答案 4 :(得分:1)

java -Xmx512m ...

会有所帮助

答案 5 :(得分:1)

据推测,您正在将XML文档写入流中,在这种情况下,您不需要将整个xml doc保存在内存中,因为您可以在构建它时将其写入流中。