【问题标题】:OutOfMemoryError in XML JDOM parser in JavaJava 中 XML JDOM 解析器中的 OutOfMemoryError
【发布时间】:2014-06-06 18:25:52
【问题描述】:

为 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): 致命异常: main 06-05 12:45:58.788: E/AndroidRuntime(10068): java.lang.OutOfMemoryError: [内存耗尽] 06-05 12:45:58.788: E/AndroidRuntime(10068): 在 dalvik.system.NativeStart.main(Native 方法)

我假设代码在这里卡住了:

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

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

【问题讨论】:

  • 使用 Sax 或 Pull 解析器。它专为大型 XML 文件设计
  • XMLPullParser 的 JDOM Parser 不是修改版(写的代码更少)吗?我将尝试 SAX 解析器。
  • 推荐使用developer.android.com/reference/org/xmlpull/v1/…,因为它更简单、更新。
  • 你怎么看? xpp.setInput( new StringReader ( "&lt;foo&gt;Hello World!&lt;/foo&gt;" ) ); 如何从文件中获取 Xml 字符串,同时避免 OutOfMemory 错误?我的意思不是“Hello World!
  • 使用setInput (InputStream)。没关系,不用把所有文档都加载到内存中

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


【解决方案1】:

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

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

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

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

解决办法是:

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

【讨论】:

    【解决方案2】:

    按照 DarkDarker 的建议,使用 XmlPullParser 类。使用带有 Reader 的 setInput() 或带有 InputStream 和编码名称(可能是“UTF-8”)的 setInput()。然后,您可以使用解析器一次在文档中移动一个元素,并在执行过程中构建您的列表。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多