Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分析csv文件时出现Android OutOfMemoryError_Android_Multithreading_Csv_Out Of Memory - Fatal编程技术网

分析csv文件时出现Android OutOfMemoryError

分析csv文件时出现Android OutOfMemoryError,android,multithreading,csv,out-of-memory,Android,Multithreading,Csv,Out Of Memory,我有一个应用程序可以在线下载csv文件,然后将其保存在本地,这样即使离线,该应用程序也可以工作。我的问题是,当用户关闭应用程序,然后立即再次打开它时,应用程序在解析保存的csv文件时挂起,并抛出OutOfMemoryError。然而,我注意到,当我在几分钟后再次打开应用程序时,它工作正常。 下载、解析和保存在不同的线程上完成。 解决这个问题的方法是什么?一种可能性:内存不足错误可能更多地与GC过度工作有关,而不是与实际内存不足有关。如果分配大块内存,然后释放它们,然后再分配更大的内存,那么就会出

我有一个应用程序可以在线下载csv文件,然后将其保存在本地,这样即使离线,该应用程序也可以工作。我的问题是,当用户关闭应用程序,然后立即再次打开它时,应用程序在解析保存的csv文件时挂起,并抛出OutOfMemoryError。然而,我注意到,当我在几分钟后再次打开应用程序时,它工作正常。 下载、解析和保存在不同的线程上完成。
解决这个问题的方法是什么?

一种可能性:内存不足错误可能更多地与GC过度工作有关,而不是与实际内存不足有关。如果分配大块内存,然后释放它们,然后再分配更大的内存,那么就会出现这样的情况:大量大块的空闲内存占用空间,但由于不够大而无法使用。GC正疯狂地尝试移动数据,并将这些数据块合并到一个连续的块中以供下一次分配,但它不会因为花费太长而看起来很糟糕,它只会抛出OutOfMemory异常,即使理论上90%的内存是可用的(如果您能给它一分钟的话,它也会可用)

就你而言,我怀疑ArrayList。它保存一个引用数组。添加条目时,它会添加到数组中。当它运行结束时,它分配一个新的、更大的,并释放旧的。如果你让它忙的话,这些丢弃的东西就会堆积起来。哈希表也有类似的问题。LinkedList和TreeMap没有,因为它们使用的是少量内存

我对安卓不太了解,但我猜当你短暂关闭它时,应用程序并没有真正关闭,所以当你重新启动它时,它会像以前一样自由内存碎片化执行。如果您等待一段时间,它可能是一个新的执行。即使不是,GC也有时间来清理,你很好

您想要的解决方案可能是在每次“启动”系统时强制执行垃圾收集(System.gc()。它让GC有机会在为您分配空间之前将所有内容整理好,而且不会花费太长时间。从某种意义上说,您正在授予GC将您的程序锁定半秒钟的权限,而GC本身不会这样做。(如果是这样的话,它会选择一个尴尬的时间去做——比如说,当用户输入文本时。)

通过使用链接集合避免大型阵列是另一种解决方案,但阵列速度很快,当您可以腾出用户半秒钟的时间时,就没有理由切换

希望这有帮助。如果这次不是问题的话,也许下次会是


添加:不幸的是,System.gc()只是一个“建议”。它可能没有做我们希望它做的工作。或者你可能会在电话后遇到麻烦。我之前应该提到的另一个大修正是将ArrayList的初始大小设置为非常大的,如果这是您正在使用的。使它的大小达到所需大小的两到三倍可能会在一次运行中为您节省十倍的内存量,同时也可以节省时间。这适用于任何基于数组的结构(哈希表和普通数组)。除此之外,基于指针的结构(如LinkedList)如果能够克服它们的缺点,就不会有这个问题。

文件有多大?你是不是一下子就把它读入了记忆?嗨@RalphChapin,你的建议强制垃圾收集有点帮助。我看到了一些改进,所以我会接受答案,但它并没有完全解决问题。。。我想我错过了什么。我将再次检查我的代码。谢谢@SimpleMody:我把我的答案扩大了一点。我的原著有点理论化,但希望能让你意识到可能存在的GC问题,不管你有没有碰到这个问题。(如果System.gc()有帮助的话,它可能是。)我添加了另一个实用的修复程序和一个不太实用的修复程序。(尽管出于这个原因,我经常使用LinkedList,但当列表大小变化很大时,从微秒到微秒不等。)