Saxon - 转换时内存不足
问题描述:
我需要帮助,试图找出进行转换时可能导致内存异常的原因。Saxon - 转换时内存不足
的代码是这样的:
Transformer transformer = cachedXSLT.newTransformer();
String strXMLInput = this.toString();
StringReader xmlReader = new StringReader(strXMLInput);
transformer.transform(new StreamSource(xmlReader), result);
凡cachedXSLT是一个模板,并导致javax.xml.transform.Result中一个
日志显示此:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:4138)
at java.util.Arrays.copyOf(Arrays.java:3870)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:119)
at java.io.PrintStream.write(PrintStream.java:454)
at sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:355)
at sun.nio.cs.StreamEncoder$CharsetSE.implFlushBuffer(StreamEncoder.java:425)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:138)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:187)
at java.io.PrintStream.write(PrintStream.java:501)
at java.io.PrintStream.print(PrintStream.java:643)
at java.io.PrintStream.println(PrintStream.java:780)
at net.sf.saxon.StandardErrorListener.error(StandardErrorListener.java:210)
at net.sf.saxon.Controller.recoverableError(Controller.java:865)
at net.sf.saxon.trans.Mode.reportAmbiguity(Mode.java:593)
at net.sf.saxon.trans.Mode.getRule(Mode.java:257)
at net.sf.saxon.trans.RuleManager.getTemplateRule(RuleManager.java:160)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:329)
at net.sf.saxon.instruct.ApplyTemplates$ApplyTemplatesPackage.processLeavingTail(ApplyTemplates.java:527)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:317)
at net.sf.saxon.instruct.ApplyTemplates$ApplyTemplatesPackage.processLeavingTail(ApplyTemplates.java:527)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:317)
at net.sf.saxon.instruct.ApplyTemplates.apply(ApplyTemplates.java:210)
at net.sf.saxon.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:174)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:556)
at net.sf.saxon.instruct.Instruction.process(Instruction.java:93)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:296)
at net.sf.saxon.instruct.Choose.processLeavingTail(Choose.java:686)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:556)
at net.sf.saxon.instruct.Instruction.process(Instruction.java:93)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:296)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:556)
at net.sf.saxon.instruct.Instruction.process(Instruction.java:93)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:296)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:556)
at net.sf.saxon.instruct.Template.applyLeavingTail(Template.java:203)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:345)
at net.sf.saxon.instruct.ApplyTemplates.defaultAction(ApplyTemplates.java:378)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:333)
at net.sf.saxon.Controller.transformDocument(Controller.java:1807)
at net.sf.saxon.Controller.transform(Controller.java:1621)
分析堆其显示堆主要被ByteArrayOutputStream占用
什么可能一旦在Introscope中使用的堆大约60%,就会生成Java堆空间。
任何想法?
答
您在这里提出了同样的问题
https://saxonica.plan.io/issues/3488
我引用我的回答:
撒克逊不使用任何ByteArrayOutputStream实例内部;我认为唯一的例子就是你(可能)提供的变形结果。结果有多大?你为什么把结果放在ByteArrayOutputStream中?
其实看着堆栈跟踪我们:
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:187)
at java.io.PrintStream.write(PrintStream.java:501)
at java.io.PrintStream.print(PrintStream.java:643)
at java.io.PrintStream.println(PrintStream.java:780)
at net.sf.saxon.StandardErrorListener.error(StandardErrorListener.java:210)
at net.sf.saxon.Controller.recoverableError(Controller.java:865)
at net.sf.saxon.trans.Mode.reportAmbiguity(Mode.java:593)
所以这里ByteArrayOutputStream似乎是由StandardErrorListener警告消息输出目的地。你有没有重定向这个输出?
你还没有说过你使用的撒克逊版本:它看起来像一个旧的,由行号来判断。
摆脱模板规则中的歧义以避免警告消息可能是个好主意:在模板规则中放置优先级属性,其中多个规则可以匹配相同的节点。
你可以包含你的JVM参数吗?此外,您正在处理的数据集有多大? – bated
@bated由于这是一个企业环境,我甚至不知道JVM参数,我所知道的是每个JVM都有1.5GB的分区。该数据集将在每个请求dinamically –
请发布[mcve]以获得更好的帮助。 – kjhughes