【问题标题】:Use of SAX parser in Android - OutOfMemory Issue在 Android 中使用 SAX 解析器 - OutOfMemory 问题
【发布时间】:2010-03-14 21:21:40
【问题描述】:

一段时间以来,我一直在使用 SAX 解析器从各种 XML 中获取数据,但今天我正在努力解决一个新的问题,即使用大量的 XML(与以前的相比。这里大约 12k 行)里面有很多重复的项目。大多数时候,项目是块的一部分:

  <content>

  <item lbl="blabla">
    <item lbl="blabla"/>
    <item lbl="blabla"/>
  </item>

  <item lbl="blabla">
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
    <item lbl="blabla"/>
  </item>
</content>

blabla 部分当然会发生变化......但是,我想保留项目的结构(它们是标题和副标题)。为此,我为每个 blabla 附加了一个开始和结束标记 &lt;itemx&gt;blabla&lt;/itemx&gt;,其中 x 是项目树中的位置(1、2、3 或 4)。 稍微有问题的部分是,我创建了数千个无用的对象,而垃圾收集器在解析器之后没有时间清理,不可避免的 OutOfMemory 出现在我面前...... 我不知道如何处理它;最好的技术是如果我可以获取&lt;content&gt;&lt;/content&gt; 的全部内容,但我不确定这是否可以使用 SAX 解析器。

欢迎任何帮助,非常感谢任何解决方案...

【问题讨论】:

    标签: android parsing sax out-of-memory


    【解决方案1】:

    如果您尝试读取的数据超出了可用内存,那么您需要持久化数据以释放内存以继续读取。

    您是否考虑在阅读时将数据存储在sqlite database 中?

    您还应该避免创建大量无用的临时对象,您是否可以通过改变单个对象或小对象池来避免垃圾堆积?

    如果您希望在内存中获取整个文档树,那么您应该使用 DOM 解析器(Android 上为此提供了DocumentBuilder。)但是,如果您使用 SAX 解析器的内存不足,很有可能 DOM 解析器也将耗尽,除非您的 SAX 事件正在创建和销毁大量对象实例。

    【讨论】:

    • 确实,我将数据存储在 SQLite 数据库中,但仅在解析结束时...再次,是的,我正在创建大量对象,因为我试图保持项目树...不幸的是,我没有其他选择可以保留它...感谢您的回答,它证实了我的恐惧... :)
    • 您可以随时尝试使用DocumentBuilder,因为它旨在以通用方式为您保存整棵树。
    【解决方案2】:

    在大多数情况下,您不能“以足够快的速度创建对象,以至于 GC 跟不上”。事实上,当需要进行 GC 时,您的整个应用程序会暂停直到它完成,因此您无法提前完成。

    唯一的例外是位图,它经过了一些特殊处理——它们计入 Java 堆,即使它们的分配没有发生在它上面。这很好,除了位图的内存在其终结器运行之前不会被释放,并且终结器确实与垃圾收集分开运行并且不会阻塞应用程序。所以创建一堆位图并简单地放开它们(不调用该方法显式释放位图的内存)确实会导致内存不足的异常。

    但是,如果您不分配(并放弃)位图对象,您还有其他问题,可能只是...没有足够的内存来进行所有分配。您可以使用 hat 工具(以及在较小程度上使用 DDMS 中的简单 Java 堆信息)来查看您分配的哪些空间占用了这么多空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 2012-09-17
      相关资源
      最近更新 更多