0

我在我的 Android 项目中使用 Simple 2.4.1 库。尝试处理 700 kB(约 6k 行)的 XML 文件时出现此 OutOfMemory 错误 - 这里的处理意味着读取文件,进行一些计算,然后将结果写入新文件。它适用于 600 kB 的文件,至少我还没有遇到同样的错误。

下面是 XML 的样子:

<items>
    <item1 id="1">
        <subitem1 id="1">
            <subsubitem1 id="a">
                <iteminfo>
                    <info>blublub</info>
                    <info>blublub</info>
                </iteminfo>
            </subsubitem1>
            <subsubitem1 id="b">
                <iteminfo>
                    <info>blublub</info>
                    <info>blublub</info>
                </iteminfo>
            </subsubitem1>
        </subitem1>
    </item1>
</items>

有什么解决方法吗?

4

3 回答 3

1

我从未使用过 SimpleXML,但据我了解,他们使用了基于 DOM 的解析方法来反序列化 2.3 版左右的 XML,以减少他们之前对 StAX 框架的依赖。Simple 也是一个 JavaSE 库,并未针对移动设备进行优化。不幸的是,这两件事经常与 OutOfMemoryError 齐头并进。

我不会声称您正在解析的 XML 无论如何都是一个“巨大的”文件,但它非常重要。根据您的程序当时使用内存的其他用途,您可能正在堆顶。以下是一些需要牢记的经验法则:

  • 预计在许多设备上,整个应用程序的可用大小不超过 16MB。这在一些较新的设备上接近 24MB,但长期以来 16MB 是标准堆大小。
  • 我还没有看到 Simple 发布的任何数字,但传统上,完全加载的 DOM 将需要大约 4 倍于它所来自的 XML 的内存大小(在您的情况下约为 3MB)。如果您从远程位置获取此 XML,它可能同时还在内存中一段时间​​。

听起来当时您的程序中发生的任何其他事情都足以吃掉除了几 MB 的堆之外的所有内容,而且您可能正处于您正在测试的任何平台的边缘。

如果您相对确定在应用程序的此操作期间无法清除其他地方的内存使用情况,我建议切换到使用 SAX 或 Pull 的基于流的解析库。

希望有帮助!

于 2011-03-10T14:29:28.017 回答
0

这可能只是一个在内存中保存太多而不用它做某事的情况。如果您考虑一下,如果您正在将一个文件读入 700kb 的内存,并且为其余的 xml 解析、您的应用程序和其他需要设备上的一些内存和 CPU 时间的应用程序添加开销,它归结为这不是一个好主意。

没有这样的解决方法,从编程的角度来看,您发现的任何解决方法都不是很好,因为您仍然试图在内存中保存 700kb 的 xml,而您可能不需要其中的大部分。

我建议您尽快找到一种方法从内存中删除这些数据以释放资源。您可以通过数据库以有意义的方式将找到的元素保存到文件或其他内容和索引中,这将允许您保存大量数据,但不是将其全部保存在内存中,您可以在数据库中查找您特别想要的数据,并且只将其带回内存。这样您就可以限制资源的使用,并且下载您的应用程序的人不会在您使用大量内存时产生怀疑。

于 2011-03-10T13:50:34.367 回答
0

You can use a SAX parser instead of parsing the entire XML document at once. SAX parsers read the XML document as a stream and appropriate events are fired when a particular tag is reached. It's not as convenient as using something like SimpleXML.

Here's a tutorial which might help: http://www.ibm.com/developerworks/opensource/library/x-android/

于 2011-03-10T14:31:32.820 回答