在Android中使用SAX解析器 - OutOfMemory问题

时间:2010-03-14 21:21:40

标签: android parsing sax out-of-memory

我一直在使用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附加一个起始和结束标记<itemx>blabla</itemx>,其中x是项目树(1,2,3或4)中的位置。 稍微有问题的部分是,我正在创建成千上万的无用对象,垃圾收集器没有时间在解析器之后进行清理,并且不可避免的OutOfMemory出现在我面前...... 我不知道如何处理它;最好的技术是如果我可以获取<content></content>的全部内容,但我不确定这是否可以使用SAX解析器。

欢迎任何帮助,任何解决方案都深深感谢...

2 个答案:

答案 0 :(得分:3)

如果您尝试阅读的数据超出可用内存,则您需要保留数据以释放内存以继续阅读。

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

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

如果您希望将整个文档树放在内存中,那么您应该使用DOM解析器(Android上可以使用DocumentBuilder)。但是,如果您使用的是内存不足SAX解析器,DOM解析器很可能也会耗尽,除非你的SAX事件正在制造和销毁大量的对象实例。

答案 1 :(得分:2)

在大多数情况下,您无法“足够快地创建对象以至于GC无法跟上”。实际上,当GC需要发生时,整个应用程序都会暂停,直到完成为止,所以你无法超越它。

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

但是如果你没有分配(和放弃)Bitmap对象,你还有其他问题,可能只是......没有足够的内存用于所有的分配。您可以使用hat工具(在较小程度上使用DDMS中的简单Java堆信息)来查看使用了大量空间的已分配内容。