Android OutOfMemoryError – 加载JSON文件

我正在处理的应用程序需要读取一个大小为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;) 

关于这一点的一个奇怪的事情是崩溃只发生在应用程序运行的第二次或第三次,让我相信每次应用程序关闭时应用程序消耗的内存都不会被垃圾收集。

任何洞察我如何解决这个问题将不胜感激。 我对以块的forms加载文件的想法持开放态度,但我不太清楚这种任务的最佳方法是什么。

谢谢

关于这一点的一个奇怪的事情是崩溃只发生在应用程序运行的第二次或第三次,让我相信每次应用程序关闭时应用程序消耗的内存都不会被垃圾收集。

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

编辑

为了回应您的后续评论,它在3中工作2次的事实表明您的应用应该按原样工作。 不可否认,如果输入文件变大,你没有太多的余地。

但有几个想法:

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

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

我不确定在“块”中读取JSON文件是个好主意。 这可能会给解析JSON带来问题……取决于你读取块的确切含义。

编辑2

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

当你说“第二次或第三次运行”时你的意思是每次你使用一个新的模拟器开始吗? 或者你的意思是离开申请并回来? (例如按home,或调用finalize())

如果您提到离开申请并重新启动它:

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

如果它发生在第二次发射你仍然使用了很多内存,应该更多地分解它。

尝试使用JsonReader在Android上有效地使用解析JSON数据。 这就像SAX解析XML一样。