引起: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时也是如此
答案 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保存在内存中,因为您可以在构建它时将其写入流中。