Java中的XML JDOM解析器中的OutOfMemoryError

时间:2014-06-05 07:56:06

标签: java android xml out-of-memory jdom

为Android开发字典应用程序。 XML文件中有一个数据库。用DOM解析器解析它是相当大的(72MB)。尝试使用JDOM解析器解析它:

List<org.jdom2.Element> list = null;
try {
    File db = new File(UnZip.DATABASE_PATH);
    InputStream stream = new FileInputStream(db);
    SAXBuilder builder = new SAXBuilder();

    //HERE CODE IS GETTING STUCK
    Document document = (Document) builder.build(stream);
    org.jdom2.Element rootNode = document.getRootElement();
    list = rootNode.getChildren(ENTRY_TAG);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JDOMException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

for (Element node : list) {
    Log.d(LOG_TAG, node.getChildText(ENT_SEQ));
    Log.d(LOG_TAG, node.getChildText(REB));
}

此代码提供OutOfMemory错误:

  

06-05 12:45:58.788:E / AndroidRuntime(10068):致命异常:主要   06-05 12:45:58.788:E / AndroidRuntime(10068):   java.lang.OutOfMemoryError:[内存耗尽] 06-05 12:45:58.788:   E / AndroidRuntime(10068):at dalvik.system.NativeStart.main(Native   方法)

我认为代码卡在这里:

Document document = (Document) builder.build(stream);

如何避免此错误并从整个XML文件(170000个条目)中找到所需的条目?

2 个答案:

答案 0 :(得分:3)

JDOM,如DOM,XOM和所有其他内存中xml模型库,将代表内存中的整个XML文档。如果您认为大多数XML文档是单字节编码(UTF-8或ASCII),然后在Java / Android中转换为2字节字符,那么内存中的XML表示通常需要大约两倍的时间内存作为原始XML文档。

与其他人相比,JDOM非常尊重内存使用(我是维护者,我有偏见,但我在内存管理方面也尝试过非常努力)。

您可以尝试使用the SlimJDOMFactory作为文档构建的一部分,但这并不会为您节省多少钱。

所有内存中的XML模型都存在同样的问题,并且(针对不同的文档大小)存在于所有平台和系统配置上。

解决方案是:

  • 找出how much memory you re allowed
  • 没有这么大的文件。 Android上的72Meg文档似乎是多余的。
  • 不立即解析整个文档,并使用流系统进行解析(SAX等)
  • 将处理卸载到服务器应用程序。
  • 他人。

答案 1 :(得分:1)

使用XmlPullParser类,如DarkDarker建议的那样。使用带有Reader的setInput()或带有InputStream和编码名称的setInput()(可能是&#34; UTF-8&#34;)。然后你可以使用解析器一次在文档中移动一个元素,随时构建列表。

所有DOM方法(包括JDOM,dom4j和其他方法)都是内存占用,因为它们在内存中构建整个文档表示。实际内存使用量通常至少是文档字节大小的4倍,字符串开销(每个字符两个字节)和文档每个组件的对象开销之间。