【问题标题】:Android OutOfMemoryError - Loading JSON FileAndroid OutOfMemoryError - 加载 JSON 文件
【发布时间】:2011-02-22 14:47:43
【问题描述】:

我正在开发的应用程序需要读取一个大小在 1.5 到 3 MB 之间的 JSON 文件。打开文件并将数据转换为字符串似乎没有问题,但是当它尝试将字符串转换为 JSONArray 时,会抛出 OutOfMemoryErrors。异常如下所示:

E/dalvikvm-heap( 5307): Out of memory on a 280-byte allocation.
W/dalvikvm( 5307): Exception thrown (Ljava/lang/OutOfMemoryError;) while throwing internal exception (Ljava/lang/OutOfMemoryError;)

关于此的一个奇怪的事情是崩溃仅在应用程序运行时每 2 次或 3 次发生,让我相信应用程序消耗的内存不会在每次应用程序关闭时被垃圾收集。

任何关于我如何解决此问题的见解将不胜感激。我对分块加载文件的想法持开放态度,但我不太确定这种任务的最佳方法是什么。

谢谢

【问题讨论】:

标签: java android json crash memory-management


【解决方案1】:

当您说“第 2 次或第 3 次运行”时,您是指每次从新的模拟器开始吗?还是您的意思是离开应用程序并返回? (例如按 home,或调用 finalize())

如果您指的是离开应用程序并重新启动它:

如果您没有在清单中设置 android:launchMode 以将活动定义为 singleInstance 或 singleTask,那么每次启动应用程序时都会创建一个新活动并将其添加到活动堆栈中。您可以轻松地在应用程序进程中运行多个活动副本,从而占用大量内存。

如果它发生在第二次启动,您仍然使用大量内存,应该将其分解更多。

【讨论】:

    【解决方案2】:

    关于此的一个奇怪的事情是崩溃仅在应用程序运行时每 2 次或 3 次发生,让我相信应用程序消耗的内存不会在每次应用程序关闭时被垃圾收集。

    这当然是可能的,如果是这种情况,那么很可能是由于内存泄漏,可以追溯到您的应用程序正在执行的操作。我认为您应该将最初的努力集中在调查这方面……而不是分块加载文件。 (我不熟悉 Android 工具链,但我确信它包括内存使用分析器或内存转储分析器。)

    编辑

    响应您的后续评论,它在 3 中 2 次运行的事实表明您的应用应该大致按原样运行。诚然,如果输入文件变大,您没有太多余地。

    不过有几个想法:

    • 与其将文件读入字符串并在字符串上运行 JSON 解析器,不如使用可以直接从流中读取的解析器。在您进行解析时,您当前的解决方案需要内存中的两个完整数据副本的空间。

    • 如果文件变得更大,您可能需要考虑一种不会创建数据的完整内存表示的设计。

    我不确定以“块”形式读取 JSON 文件是否是个好主意。这可能会导致解析 JSON 的问题……这取决于您阅读块的确切含义。

    编辑 2

    也许您需要的是一个“类似 SAX”的 JSON 解析器;例如http://code.google.com/p/async-json-library/

    【讨论】:

    • 您是否建议加载这么多数据应该是可行的?我已经在这个应用程序上工作了三个月,而且还没有看到任何内存问题。我可以从字面上注释掉将字符串转换为 json 数组的代码行,然后一切又可以顺利运行了。
    • 感谢您的想法!我同意尝试分块读取 JSON 似乎很麻烦。您提出了一个很好的观点,即不要创建数据的多个副本。
    • 我正在研究从流中创建 JSON 对象,如果流方法不起作用,将检查 async-json-library。再次感谢!
    • 更新:我还没有 100% 接受这个解决方案(需要做更多的调试),但是我用 com.google.gson 替换了内置的 org.json 类,内存错误是走了。我认为这部分是由于 gson 库中的 JsonParser 可以从 Reader 对象构建对象和数组,这意味着创建数据的字符串表示是不必要的。
    【解决方案3】:

    尝试使用 JsonReader 在 Android 上高效地解析 JSON 数据。这就像对 XML 的 SAX 解析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 2017-09-20
      相关资源
      最近更新 更多