我正在尝试编写一个图像缓存。我正在使用WeakHashMap来保存下载的图像,并将它们显示在ImageView列表中。但是,过了一段时间我遇到了:
02-17 15:13:00.416: D/dalvikvm(11766): GC_FOR_MALLOC freed 0K, 69% free 3447K/10823K, external 21870K/22699K, paused 16ms
02-17 15:13:00.455: D/dalvikvm(11766): GC_EXTERNAL_ALLOC freed <1K, 69% free 3447K/10823K, external 21870K/22699K, paused 25ms
02-17 15:13:00.463: E/dalvikvm-heap(11766): 116160-byte external allocation too large for this process.
02-17 15:13:00.490: E/GraphicsJNI(11766): VM won't let us allocate 116160 bytes
之后我被OutOfMemoryError处理。
很明显,无论是什么,我都会用完“外部记忆”。有足够的堆可用,但这似乎并不重要。 GC似乎无法清理这个“外部内存”,尽管我所拥有的唯一引用是弱哈希和列表中的imageViews(应该只是一个实例,重用)...
有人可以帮我解释一下这个问题吗?这个外部存储器到底是什么用的?为什么GC没有清理旧图像?
编辑:我发现了导致我的内存不被释放的原因:WeakHashmap在不再引用KEYS时释放条目,而不是在未引用VALUES时释放条目。我的主要问题仍然存在:外部记忆是什么?
答案 0 :(得分:0)
我相信基础android有16 MB的堆内存,它用于所有程序的对象,包括你的hashmap,所以没有太多的内存供你使用。某些具有自定义ROM的单个设备可能有更多空间,但默认情况下为16 MB。它实际上是在Android本身编码的,特别是在文件frameworks/base/core/jni/AndroidRuntime.cpp
中:
AndroidRuntime::startVm()
...
strcpy(heapsizeOptsBuf, "-Xmx");
property_get("dalvik.vm.heapsize", heapsizeOptsBuf+4, "16m");
//LOGI("Heap size: %s", heapsizeOptsBuf);
opt.optionString = heapsizeOptsBuf;
mOptions.add(opt);
您可以使用recycle()
方法和其他一些技术来最小化应用程序的内存占用,但如果您需要存储超过16 MB的数据,那么您将非常幸运。< / p>
答案 1 :(得分:0)
您遇到的问题是您正在尝试分配比可用内存更多的内存。即使你有60%的免费,如果你尝试分配61%的堆大小,你会得到一个内存不足错误。