3

我正在评估 vtd-xml 作为大型数据迁移项目的可能解决方案。输入数据为 xml 格式,如果 vtd-xml 可行,它将节省大量开发时间。我从 vtd-xml 网站运行示例处理巨大的 XML 文档(大于 2GB):http: //vtd-xml.sourceforge.net/codeSample/cs12.html

我成功处理了 500Mb,但得到了可怕的 java.lang.OutOfMemoryError: Java heap space error with a 4Gb file。

  1. JVM 参数:-Xmn100M -Xms500M -Xmx2048M。
  2. JVM 参数:-Xmn100M -Xms500M -Xmx4096M。

使用 Maven:

  1. 设置 MAVEN_OPTS=-Xmn100M -Xms500M -Xmx2048M
  2. 设置 MAVEN_OPTS=-Xmn100M -Xms500M -Xmx4096M

注意:我已经使用 JVM 参数的各种组合对其进行了测试。

我研究了 vtd-xml 站点和 API 文档,并在这里和其他地方浏览了许多问题。所有的 awnsers 都指向将 JVM 内存设置得更高或添加更多的物理内存。vtd-xml 网站指的内存使用量是 xml 文件大小的 1.3x-1.5x,但如果使用 64 位,则应该能够处理比可用内存大得多的文件。当然,添加 64Gb 内存来处理 35Gb xml 文件也是不可行的。

环境:

视窗 7 64 位。6Gb 内存。(关闭所有其他应用程序,85% 内存可用)

java版本“1.7.0_09”

Java(TM) SE 运行时环境 (build 1.7.0_09-b05)

Java HotSpot(TM) 64 位服务器 VM(内部版本 23.5-b02,混合模式)

日蚀靛蓝

Maven 2

从 Eclipse 和 Maven 运行该示例会引发 Out of memory 异常。

示例代码:

 import com.ximpleware.extended.VTDGenHuge;
 import com.ximpleware.extended.VTDNavHuge;
 import com.ximpleware.extended.XMLMemMappedBuffer;

 public class App {

/* first read is the longer version of loading the XML file */
public static void first_read() throws Exception{
XMLMemMappedBuffer xb = new XMLMemMappedBuffer();
    VTDGenHuge vg = new VTDGenHuge();
    xb.readFile("C:\\Temp\\partial_dbdump.xml");
    vg.setDoc(xb);
    vg.parse(true);
    VTDNavHuge vn = vg.getNav();
    System.out.println("text data ===>" + vn.toString(vn.getText()));
}   

/* second read is the shorter version of loading the XML file */
public static void second_read() throws Exception{
    VTDGenHuge vg = new VTDGenHuge();
    if (vg.parseFile("C:\\Temp\\partial_dbdump.xml",true,VTDGenHuge.MEM_MAPPED)){
        VTDNavHuge vn = vg.getNav();
        System.out.println("text data ===>" + vn.toString(vn.getText()));
    }
}

public static void main(String[] s) throws Exception{
    first_read();
    //second_read();
}

}

错误:

 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.ximpleware.extended.FastLongBuffer.append(FastLongBuffer.java:209)
at com.ximpleware.extended.VTDGenHuge.writeVTD(VTDGenHuge.java:3389)
at com.ximpleware.extended.VTDGenHuge.parse(VTDGenHuge.java:1653)
at com.epiuse.dbload.App.first_read(App.java:14)
at com.epiuse.dbload.App.main(App.java:29)

任何帮助,将不胜感激。

4

2 回答 2

3

您告诉 Java 它的最大堆大小为 2GB,然后要求它处理一个 4GB 大的 XML 文件。

为了有机会完成这项工作,您需要定义一个大于您尝试处理的文件大小的最大堆 - 或者将处理机制更改为不需要内存中的整个文件的处理机制同时。

从他们的网站,

世界上内存效率最高的(XML 文档大小的 1.3 倍~1.5 倍)随机访问 XML 解析器。

这意味着对于一个 4GB 的文件,您需要大约 6GB 的最大堆大小,假设您的应用程序不需要任何其他内存。

试试这些 JVM 参数:

-Xmn100M -Xms2G -Xmx6G

您可能仍然会耗尽内存,但至少现在您有机会。

哦,是的 - 您可能会发现您的 Java 现在无法启动,因为操作系统无法为 Java 提供它所要求的内存。如果发生这种情况,您需要一台具有更多 RAM(或者可能是更好的操作系统)的机器

于 2012-11-16T15:10:28.097 回答
1

您必须使用扩展 vtd-xml 进行加载...标准 vtd-xml 仅支持最大 2GB 的文档加载...扩展 vtd-xml 支持最大 256 GB 的文档。它还启用延迟加载(即内存映射)。您完全不会失去 XPath 的舒适性和效率。

于 2016-05-02T02:04:40.777 回答