【发布时间】:2015-05-27 20:15:21
【问题描述】:
在我的应用程序中,我正在处理一些文件。其中一些可能很大。当遇到一个文件太大而无法放入内存时,我想跳过它并礼貌地向用户解释这一点,最后显示其他文件的部分结果。这些文件是用BufferedReader 读入的,它在使用后被丢弃,没有原生的东西。我意识到加载它可能需要比文件大小更多的内存,所以我正在检查文件大小的 3 倍是否可用。
问题是我找不到检测应用程序剩余可用内存的方法,并且在加载某些文件时总是会出现OutOfMemoryError。我已经搜索了所有内容,但对此没有明确的答案。我没有运气尝试过的事情:
1)
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
这会返回一个巨大的数字,几百兆字节,这显然远远超过了每应用程序堆数兆字节的限制。不用说,应用程序崩溃了。
2)
Runtime info = Runtime.getRuntime();
long freeSize = info.freeMemory();
这个数字通常在几兆左右,看起来是正确的,但如果与它比较 3 倍的文件大小,仍然会出现 OutOfMemoryError
3)
Runtime info = Runtime.getRuntime();
long freeSize = info.maxMemory() - info.totalMemory();
比上面的数字大一点,但还是会发生崩溃
4)
Debug.MemoryInfo mi = new Debug.MemoryInfo();
Debug.getMemoryInfo(mi);
我什至无法理解这个对象中的数据,但我觉得在这种情况下它不会有用
5)
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
long freeMem = activityManager.getMemoryClass()*1024*1024 - Runtime.getRuntime().totalMemory();
再次崩溃。
6)
打电话
Runtime.getRuntime().gc();
在每个文件读取之前没有任何影响
处理的性质(正则表达式匹配)要求整个文件存在于内存中并且不能以块的形式加载。这是因为正则表达式需要随机访问字符读取,这对于文本文件是不可能的,因为字符集编码不同,至少性能不可接受。
那么这个看似简单的任务如何实现呢?
【问题讨论】:
-
你在“处理”什么
-
你的应用程序应该使用更少的内存...没有其他办法...并不总是OOME意味着没有可用内存...也可能是堆碎片问题...
-
@tyczj 正则表达式搜索,没什么特别的
标签: java android memory garbage-collection out-of-memory