gpt4 book ai didi

xslt - Ant XSLT 任务的文件集内存不足/未释放内存

转载 作者:行者123 更新时间:2023-12-03 03:55:57 27 4
gpt4 key购买 nike

我有一个大的 (1.9 GB) XML 文件,其中包含我希望每月插入 MySQL 数据库的数据。我为此编写了一个 Ant 脚本。

Ant XSLT 任务无法处理这么大的一个文件,因此我有一项任务使用 xml_split(来自 xml-twig-tools)将 1.9 GB 的 xml 文件拆分为大约 4 MB 的较小 xml 文件。

一切都很顺利。

我使用以下 Ant xml 对所有这些 XML 文件运行 XSLT 任务:

    <target name="xsltransform" depends="split" description="Transform XML to SQL...">
<xslt basedir="${import.dir}/"
destdir="${import.dir}/sql/"
style="${xsl.filename}" force="true">
<mapper type="glob" from="*.xml" to="*.sql" />
<factory name="net.sf.saxon.TransformerFactoryImpl"/>
</xslt>
</target>

问题是,一旦它在第一个 XML 文件上启动,我就会看到 linux top 中的“RES”内存随着每个下一个 XML 文件而增长。由于它正在处理多个(不相关的)xml 文件,我怀疑它会在每个 xml 文件的翻译之间释放内存。好吧,事实并非如此……在 200 个 4MB 的 xml 文件之后,java 抛出内存不足异常:

BUILD FAILED
/var/lib/hudson/jobs/EPDB_Rebuild_Monthly/workspace/trunk/buildfiles/buildMonthly.xml:67: java.lang.OutOfMemoryError: Java heap space
at net.sf.saxon.tinytree.TinyTree.ensureNodeCapacity(Unknown Source)
at net.sf.saxon.tinytree.TinyTree.addNode(Unknown Source)
at net.sf.saxon.tinytree.TinyBuilder.startElement(Unknown Source)
at net.sf.saxon.event.Stripper.startElement(Unknown Source)
at net.sf.saxon.event.ReceivingContentHandler.startElement(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at net.sf.saxon.event.Sender.sendSAXSource(Unknown Source)
at net.sf.saxon.event.Sender.send(Unknown Source)
at net.sf.saxon.event.Sender.send(Unknown Source)
at net.sf.saxon.Controller.transform(Unknown Source)
at org.apache.tools.ant.taskdefs.optional.TraXLiaison.transform(TraXLiaison.java:194)
at org.apache.tools.ant.taskdefs.XSLTProcess.process(XSLTProcess.java:812)
at org.apache.tools.ant.taskdefs.XSLTProcess.execute(XSLTProcess.java:408)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:390)
at org.apache.tools.ant.Target.performTasks(Target.java:411)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1360)
at org.apache.tools.ant.Project.executeTarget(Project.java:1329)

我可以采取一些措施来防止 XSLT 任务耗尽我的所有内存吗?或者我应该重新考虑我的方法?

最佳答案

我们都同意它应该释放内存,但由于它没有释放内存,您可以尝试将 xslt 任务分解为单独的调用。例如,使用 Ant Contrib's for task

<for param="file">
<fileset dir="${import.dir}"/>
<sequential>
<xslt in="@{file}"
destdir="${import.dir}/sql/"
style="${xsl.filename}" force="true">
<mapper type="glob" from="*.xml" to="*.sql" />
<factory name="net.sf.saxon.TransformerFactoryImpl"/>
</xslt>
</sequential>
</for>

如果这不起作用,那么由于您使用的是 Saxon,您可以 calling Saxon's java classes directly在 fork 的 JVM 中。例如,

<java classname="net.sf.saxon.Transform" failonerror="true" fork="true">
<arg value="-s:${import.dir}" />
<arg value="-xsl:${xsl.filename}" />
<arg value="-o:${import.dir}/sql" />
</java>

或者你可以两者都尝试

<for param="file">
<fileset dir="${import.dir}"/>
<sequential>
<basename property="@{file}.base" file="@{file}" suffix="xml"/>
<java classname="net.sf.saxon.Transform" failonerror="true" fork="true">
<arg value="-s:@{file}" />
<arg value="-xsl:${xsl.filename}" />
<arg value="-o:${import.dir}/sql/${@{file}.base}.sql" />
</java>
</sequential>
</for>

为了获得奖励积分,您可以尝试通过并行执行来加快速度。

<for param="file">
<fileset dir="${import.dir}"/>
<parallel>
<basename property="@{file}.base" file="@{file}" suffix="xml"/>
<java classname="net.sf.saxon.Transform" failonerror="true" fork="true">
<arg value="-s:@{file}" />
<arg value="-xsl:${xsl.filename}" />
<arg value="-o:${import.dir}/sql/${@{file}.base}.sql" />
</java>
</parallel>
</for>

关于xslt - Ant XSLT 任务的文件集内存不足/未释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5806257/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com