java - 当 10Mb 空闲时,Android 分配 4Mb 时出现 OutOfMemoryError

标签 java android out-of-memory

我不明白为什么在 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)

最佳答案

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

例如,假设我们有一个 3K 堆,并且我们进行了三个 1K 分配:A、B 和 C。现在,我们的堆已耗尽,因为我们使用了 3K 堆中的所有 3K。

现在,A 被垃圾收集了。我们的堆在 1K block 中有 1K 可用空间。如果我们尝试分配 1.5K block ,我们将收到 OutOfMemoryError,因为总体堆空间不足。

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

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

关于java - 当 10Mb 空闲时,Android 分配 4Mb 时出现 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19891160/

相关文章:

android - 无法将现有 SQLite 数据库导入 Android 应用程序

Android 模拟器完全放电 - 运行 telnet power 命令导致模拟器崩溃

linux交换空间从不释放内存

android - 如何在 android 中使用自定义相机类编写 Exif 数据?

java - 由于资源泄漏导致 java 堆空间内存不足问题

Java 堆空间 - -Xmx 是如何工作的?

java - Java未在异步线程上显示运行时错误/异常

java - 对象可以继承吗?

java - 如何从弃用的任务转移到 ApiFuture for firebase admin SDK 5.4 及更高版本

java - 无法从我的 Oauth 服务器获取 token