0

我不明白为什么在 4Mb 分配时会发生 OutOfMemoryError,因为我有 10Mb 的可用内存。为什么?(安卓 4.1.2)

日志文件:

11-10 14:37:12.503: D/MyApp(1570): debug. =================================
11-10 14:37:12.503: D/MyApp(1570): debug.heap native: allocated 3.32MB of 16.61MB (0.35MB free)
11-10 14:37:12.503: D/MyApp(1570): debug.memory: allocated: 30.00MB of 32.00MB (8.00MB free)
11-10 14:37:12.524: D/dalvikvm(1570): GC_FOR_ALLOC freed 10K, 29% free 22176K/31111K, paused 16ms, total 16ms
11-10 14:37:12.524: I/dalvikvm-heap(1570): Forcing collection of SoftReferences for 4431036-byte allocation
11-10 14:37:12.533: D/dalvikvm(1570): GC_BEFORE_OOM freed <1K, 29% free 22176K/31111K, paused 11ms, total 11ms
11-10 14:37:12.533: E/dalvikvm-heap(1570): Out of memory on a 4431036-byte allocation.
11-10 14:37:12.533: I/dalvikvm(1570): "Thread-67" prio=5 tid=10 RUNNABLE
11-10 14:37:12.533: I/dalvikvm(1570):   | group="main" sCount=0 dsCount=0 obj=0xb59cfd68 self=0xb8e22fd8
11-10 14:37:12.533: I/dalvikvm(1570):   | sysTid=1587 nice=0 sched=0/0 cgrp=[fopen-error:2] handle=-1193135816
11-10 14:37:12.533: I/dalvikvm(1570):   | schedstat=( 0 0 0 ) utm=245 stm=91 core=0
11-10 14:37:12.533: I/dalvikvm(1570):   at android.graphics.Bitmap.nativeCreate(Native Method)
11-10 14:37:12.533: I/dalvikvm(1570):   at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
...
11-10 14:37:12.533: W/dalvikvm(1570): threadid=10: thread exiting with uncaught exception (group=0xb4ef4288)
11-10 14:37:12.543: E/AndroidRuntime(1570): FATAL EXCEPTION: Thread-67
11-10 14:37:12.543: E/AndroidRuntime(1570): java.lang.OutOfMemoryError
11-10 14:37:12.543: E/AndroidRuntime(1570):     at android.graphics.Bitmap.nativeCreate(Native Method)
11-10 14:37:12.543: E/AndroidRuntime(1570):     at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
11-10 14:37:12.543: E/AndroidRuntime(1570):     at android.graphics.Bitmap.createBitmap(Bitmap.java:620)
4

2 回答 2

2

OutOfMemoryError当没有单个连续的堆空间块满足您请求的大小时,您将得到一个。当仍然有大量可用的堆空间时会发生这种情况,但这都是一系列较小的不连续块。

例如,假设我们有一个 3K 堆,我们分配了三个 1K:A、B 和 C。现在,我们的堆已经用完了,因为我们用完了 3K 堆中的所有 3K。

现在,A 被垃圾回收了。我们的堆在 1K 块中有 1K 的可用空间。如果我们尝试分配一个 1.5K 的块,我们将得到一个OutOfMemoryError,因为总体上没有足够的堆空间。

现在,C 被垃圾收集了。但是,A 和 C 是不连续的 - B 在它们之间。A 和 C 的内存不能合并为一个块。因此,虽然我们有 2K 的可用堆空间,但我们仍然会OutOfMemoryError因为 1.5K 的分配请求而失败,因为没有单个连续的内存块可以满足所需的大小。只有当 B 也被垃圾回收时,我们的块才会合并回 3K 堆,此时我们可以授予 1.5K 分配。

这就是为什么在处理大图像或其他大块(例如,使用inBitmapin BitmapOptions)时,智能地回收您自己分配的内存在 Android 中很重要。

于 2013-11-10T15:34:56.127 回答
0

出现此错误的原因有很多,众所周知,这是我们在加载高清图像时遇到的非常常见的问题,或者由于始终使用位图,解决方案是:

  1. 使用低清晰度图像。
  2. 调整和回收位图。

这里有一些有用的链接: Memory Leak and Out of memory Error

使用 List、LinkedList 和 HashMap 的内存泄漏和内存不足错误

使用 LRU 缓存的内存泄漏和内存不足错误

使用磁盘 LRU 缓存的内存泄漏和内存不足错误

于 2013-11-10T17:57:03.673 回答