android - OutOfMemory 错误,但有可用内存

标签 android bitmap jvm android-3.0-honeycomb dalvik

我看到一个很奇怪的问题。本质上,有时大的位图内存分配会失败,即使显然有大量内存。有许多帖子似乎提出了类似的问题,但它们都与 pre-honeycomb android 有关。我的理解是图像现在是在堆上分配的,而不是一些外部内存。无论如何,请查看下面的日志:

    10-14 13:43:53.020: INFO/dalvikvm-heap(31533): Grow heap (frag case) to 40.637MB for 942134-byte allocation
    10-14 13:43:53.070: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 126K, 11% free 41399K/46343K, paused 31ms
    10-14 13:43:53.130: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 920K, 13% free 40478K/46343K, paused 30ms
    10-14 13:43:53.180: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 1026K, 13% free 40479K/46343K, paused 30ms
    10-14 13:43:53.250: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 931K, 12% free 41193K/46343K, paused 31ms
    10-14 13:43:53.250: INFO/dalvikvm-heap(31533): Grow heap (frag case) to 41.313MB for 1048592-byte allocation
    10-14 13:43:53.280: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed <1K, 11% free 42217K/47431K, paused 31ms
    10-14 13:44:01.520: DEBUG/dalvikvm(31533): GC_CONCURRENT freed 3493K, 15% free 40646K/47431K, paused 3ms+9ms
    10-14 13:44:08.130: DEBUG/dalvikvm(31533): GC_EXPLICIT freed 16461K, 47% free 25527K/47431K, paused 3ms+6ms
    10-14 13:44:09.150: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 1007K, 45% free 26191K/47431K, paused 35ms
    10-14 13:44:09.160: INFO/dalvikvm-heap(31533): Grow heap (frag case) to 29.334MB for 3850256-byte allocation
    10-14 13:44:09.200: DEBUG/dalvikvm(31533): GC_CONCURRENT freed 0K, 37% free 29951K/47431K, paused 2ms+4ms
    10-14 13:44:11.970: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 1878K, 38% free 29784K/47431K, paused 37ms
    10-14 13:44:12.410: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed 62K, 36% free 30441K/47431K, paused 32ms
    10-14 13:44:12.440: DEBUG/dalvikvm(31533): GC_FOR_ALLOC freed <1K, 32% free 32325K/47431K, paused 32ms
    10-14 13:44:12.440: INFO/dalvikvm-heap(31533): Forcing collection of SoftReferences for 3850256-byte allocation
    10-14 13:44:12.480: DEBUG/dalvikvm(31533): GC_BEFORE_OOM freed 124K, 33% free 32200K/47431K, paused 37ms
    10-14 13:44:12.480: ERROR/dalvikvm-heap(31533): Out of memory on a 3850256-byte allocation.

我很抱歉包含了这么多日志记录,我希望它是相关的。我读它的方式是系统不断地重新调整堆大小,直到它最终达到堆最大值。然后,我们请求一个特别大的分配失败。显然有足够多的可用内存(大约 15 兆)。这是否意味着堆在内部是 fragment 化的并且没有足够大的连续内存段来处理我们的分配?如果是这样我该怎么办?如果不是,那又怎样?

提前致谢。

最佳答案

奇怪的行为是因为位图是在 native 堆上分配的,而不是在垃圾收集堆上分配的,但 android 只能跟踪垃圾收集堆上的对象。从 Android 2.2(或可能是 2.3)开始,这已经改变,如果您进行堆转储,分配的位图也可见。

回到问题,你的问题很可能是你手动加载的位图没有被适当释放。一个典型的问题是某些回调保持设置或 View 仍在引用位图。 另一个常见问题是,如果您手动加载大位图(而不是作为资源),当您不再需要它们时,您将需要在它们上调用 recycle(),这将从 native 内存中释放位图,因此垃圾收集器将能够正常工作。 (GC只看到GC堆上的对象,并没有从 native 堆中释放哪些对象来释放内存,实际上根本不关心它。)

我手边一直有这个小宝贝:

public static void stripImageView(ImageView view) {
    if ( view.getDrawable() instanceof BitmapDrawable ) {
        ((BitmapDrawable)view.getDrawable()).getBitmap().recycle();
    }
    view.getDrawable().setCallback(null);
    view.setImageDrawable(null);
    view.getResources().flushLayoutCache();
    view.destroyDrawingCache();
}

关于android - OutOfMemory 错误,但有可用内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7774723/

相关文章:

Android 的 View 不刷新

iphone - 弯曲位图图像 - 就像在 PS5 中一样。算法?代码?图像处理?

c - 缩放位图图像出现段错误

java - JVM 使用不同的 file.encoding 打开另一个 JVM

android - 如何暂停 Activity 直到其他 Activity 返回结果?

android - 为什么以编程方式调用电话会给出错误消息 "Internet Calling not Supported"?

c++ - 在 C++ 中将彩色位图转换为灰度

java - Adobe Flash Builder 4.7 启动失败,错误代码为 "Failed to create the Java Virtual Machine"

debugging - 我正在调试的 Scala 代码对调试器有影响吗?

android - 带有水平 ScrollView 的图库