5

If I have:

Bitmap bitmap = Bitmap.create(..); // instance a
bitmap = Bitmap.create(...); // instance b
bitmap = null;
bitmap = Bitmap.create(...); // instance c
bitmap.recycle();
bitmap = Bitmap.create(...); // instance d
bitmap.recycle();
bitmap = null;

Once this code is executed, which of the 4 instances are still in memory? I know .recycle() instructs the native code to deallocate all resources to that object, but there's no guarantee of when that happens.

The reason I'm asking, is let's look at the following loop:

Bitmap bitmap = null;

while (true) {
    bitmap = Bitmap.create(...);    
}

This I assume will eventually crash the app (out of memory)? If so, how should this loop be rewritten? (If I'm using bitmap to animate and display changed state).

4

2 回答 2

1

Java(以及 Android 的扩展)使用异步垃圾收集来清理分配的内存。收集器在后台运行,释放它可以释放的内存。这意味着,您在任何时候都无法保证*有多少无法访问的对象已被清理,而哪些对象仍处于待处理状态。

在您的第一个代码块完成执行后,可能所有四个Bitmap对象都仍然存在于堆上,但在某个时候垃圾收集器将运行,确定它们都不再可访问,并释放它们相关的内存。

在您的第二个代码块中也是如此;即使它们不再可访问,堆上仍会存在一些任意数量的对象,但是 GC 会在发生这种情况时尽最大努力清理它们。在实践中,GC非常擅长清理此类短期对象,因此它甚至可以跟上您的循环(但这不是保证)。

JVM/ART 将尽最大努力避免出现这种OutOfMemory情况,包括激进的最后一次垃圾收集,以尝试回收任何可能的内存以保持应用程序运行。因此,您的第二个循环不太可能导致任何问题,但它对您来说很容易测试。

希望您不是真的创建并立即丢弃数千个Bitmap对象;大概它们至少被使用了一段时间,在此期间,您不仅仅是创建更多Bitmap未使用的 s (如果是这样,那是您的问题)。

* 有一些技巧,例如 using PhantomReference,确实可以让您监控垃圾收集的状态,但是这些技巧会给 GC 带来更多负担,因此通常不是一个好主意 - 也不是必需的。

于 2016-07-23T23:26:42.977 回答
0

Android 使用 DalvikVM,其功能与 Java 几乎相似。除非需要,否则它不会回忆。

MAT是使用 hprof for android 分析内存转储的出色工具。

您可以使用 MAT 自己找到答案

于 2012-08-18T15:49:03.860 回答