Xalan XSLT - 内存堆空间不足

时间:2012-01-30 22:21:25

标签: java xslt heap xalan

我的项目有一个报告模块,它以XML的形式从数据库中收集数据,并在其上运行XSLT以生成用户所需的报告格式。此时的选项是HTML和CSV。

我们使用Java和Xalan进行与数据的所有交互。

糟糕的是,用户可以请求的其中一个报告仅为XML部分的143MB(约430,000条记录)。当它转换为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(函数等)有什么限制,这可能需要它来进行适当的清理。如果有人能指出我详细说明这些限制的资源,那将非常有帮助。

2 个答案:

答案 0 :(得分:2)

XSLT的问题在于,在进行转换时,您需要在内存中拥有整个源文档(以及结果文档)的DOM表示。对于大型XML文件,这是一个严重的问题。

您对允许流式转换的系统感兴趣,其中完整文档不必在内存中重新存在。也许STX是一个选项: http://www.xml.com/pub/a/2003/02/26/stx.html http://stx.sourceforge.net/。它与XSLT非常相似,因此如果您的XSLT样式表以直接的方式应用于XML,则将其重写为STX可能非常简单。

答案 1 :(得分:1)

我们可以通过做两件事来改善这一点。

  1. 我们采用XML源和目标格式,并将它们设置为temp。这使得初始创建和存储不在RAM中,因为数据来自数据库并且也被写回到DB。数据的句柄就是必要的。

  2. 使用Saxonica变换器。这允许一些事情,包括SAX风格的转换和XSL解析器没有的XSLT 2.0的使用。