Xalan XSLT - 内存堆空间不足
Posted
技术标签:
【中文标题】Xalan XSLT - 内存堆空间不足【英文标题】:Xalan XSLT - Out of Memory Heap Space 【发布时间】:2012-02-22 17:00:37 【问题描述】:我的项目有一个报告模块,它以 XML 的形式从数据库收集数据并在其上运行 XSLT 以生成用户所需的报告格式。此时的选项是 html 和 CSV。
我们使用 Java 和 Xalan 与数据进行所有交互。
不好的部分是用户可以请求的这些报告之一是 143MB(大约 430,000 条记录),仅用于 XML 部分。当它被转换成 HTML 时,我用完了堆空间,最多为堆保留 4096G。这是不可接受的。
似乎问题只是数据太多,但我不禁想到有一个更好的方法来处理这个问题,而不是限制客户并且无法满足功能需求。
我很高兴根据需要提供更多信息,但我不能透露太多有关该项目的信息,因为我相信你们中的大多数人都理解。此外,答案是肯定的;我同时需要所有数据:我无法对其进行分页。
谢谢
编辑
我使用的所有转换类都在 javax.xml.transform 包中。实现如下所示:
final Transformer transformer =
TransformerFactory.newInstance().newTransformer(
new StreamSource(new StringReader(xsl)));
final StringWriter outWriter = new StringWriter();
transformer.transform(
new StreamSource(new StringReader(xml)), new StreamResult(outWriter));
return outWriter.toString();
如果可能的话,我想保留 XSLT 的原样。 StreamSource
的处理方法应该允许我在处理一些数据时对其进行 GC,但我不确定 XSLT(函数等)的哪些限制可能需要它进行适当的清理。如果有人可以向我指出详细说明这些限制的资源,那将非常有帮助。
【问题讨论】:
【参考方案1】:我们可以通过做两件事来改善这一点。
我们采用 XML 源和目标格式并将它们制作成临时文件。这将初始创建和存储保持在 RAM 之外,因为数据来自数据库并且也被写回 DB。只需一个数据句柄即可。
使用Saxonica 转换器。这允许做一些事情,包括 SAX 样式的转换和 XSLT 2.0 的使用,而 Xalan 解析器不这样做。
【讨论】:
【参考方案2】:XSLT 的问题在于,在进行转换时,您需要在内存中拥有整个源文档(以及结果文档)的 DOM 表示。对于大型 XML 文件,这是一个严重的问题。
您对允许流式转换的系统感兴趣,其中完整的文档不必在内存中重新存储。也许 STX 是一种选择: http://www.xml.com/pub/a/2003/02/26/stx.html http://stx.sourceforge.net/。它与 XSLT 非常相似,因此如果您的 XSLT 样式表以直接的方式应用于 XML,则将其重写为 STX 可能非常简单。
【讨论】:
此外,最新版本的 XSLT 确实包含流功能:w3.org/TR/xslt-21/#streaming-concepts。我自己没试过。 Saxon 也支持streaming,尽管您可以为此模式编写的 XSLT 更加有限。还有更多讨论here。 是的,这就是我所指的 XSLT 2.1 版本中的新增功能。限制表现力可能是使其成为流媒体的必要条件。 查看编辑。据我了解,我已经在使用 Xalan 的流媒体选项(StreamSource
和 StreamResult
来自 javax.xml.transform.stream
包)。感谢您的回复;我什至不确定有多少人在使用这些东西。
StreamSource
是一个糟糕的类名。之所以称为StreamSource
,是因为它从InputStream
中读取数据,而不是因为Source
和Result
之间发生的转换是流式转换。以上是关于Xalan XSLT - 内存堆空间不足的主要内容,如果未能解决你的问题,请参考以下文章