使用vtd-xml加载巨大的4Gb XML文件

时间:2012-11-16 15:02:12

标签: java out-of-memory vtd-xml

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

我成功处理了500Mb但得到了可怕的java.lang.OutOfMemoryError:带有4Gb文件的Java堆空间错误。

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

和Maven一起:

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

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

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

  
    

环境:

         

Windows 7 64位。 6Gb RAM。 (关闭所有其他应用程序,85%内存avaibale)

         

java版“1.7.0_09”

         

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

         

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

         

Eclipse Indigo

         

Maven 2

  

从Eclipse和Maven运行示例会引发内存不足异常。

示例代码:

 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)

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

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

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

从他们的网站

  

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

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

尝试这些JVM参数:

  

-Xmn100M -Xms2G -Xmx6G

你可能仍然没有记忆,但至少现在你有机会。

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

答案 1 :(得分:0)

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