Java中的内存分配 - Android

5
如果我有:
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;

一旦执行此代码,哪些4个实例仍在内存中?我知道.recycle()指示本机代码释放该对象的所有资源,但不能保证何时发生。
我提出这个问题的原因是让我们看一下以下循环:
Bitmap bitmap = null;

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

我认为这可能会导致应用程序崩溃(内存耗尽)?如果是这样,应该如何重写循环?(如果我正在使用位图来动画显示更改的状态)。

2
你无法知道那些位图是否仍然存在于内存中。我认为如果你在recycle()之后调用gb(),你可以确信最后两个不在内存中了。Android开发者: 这不会同步释放像素数据;它只是允许垃圾回收器在没有其他引用时进行垃圾回收。 - Brais Gabin
2个回答

1
Java(以及扩展到Android)使用异步垃圾回收来清理分配的内存。垃圾收集器在后台运行,释放它所能释放的内存。这意味着在任何时候都不能保证已清除不可达对象的数量与仍处于等待状态的对象的数量之间的比例。第一个代码块执行完毕后,四个“Bitmap”对象仍可能存在于堆上,但是垃圾收集器会在某个时刻运行,确定它们都不再可达,并释放它们关联的内存。同样的事情也适用于您的第二个代码块;一些任意数量的对象仍将存在于堆上,即使它们不再可达,但是垃圾收集器会尽其所能在发生这种情况时清理它们。实际上,垃圾收集器非常擅长清理这样的短寿命对象,因此它甚至可以跟得上您的循环(但这并不是保证)。
JVM/ART将尽最大努力避免OutOfMemory情况,包括激进的最后一次垃圾回收,以尝试回收任何可能的内存来保持应用程序运行。因此,你的第二个循环不太可能引起任何问题,但你可以轻松测试。
希望你不是真的创建并立即丢弃数千个Bitmap对象;假设它们在使用期间至少有一段时间,你不仅仅是创建更多的未使用的Bitmap(如果是这样,那就是你的问题)。
* 有一些技巧,比如使用PhantomReference,可以让你监视垃圾回收的状态,但这些技巧会给GC增加更多负担,因此通常不是一个好主意,也不是必要的。

0

Android 使用 DalvikVM,其功能与 Java 几乎相似。它不会在不必要的情况下进行回收。

MAT 是一款优秀的工具,可以使用 hprof 分析安卓的内存转储。

你可以使用 MAT 自己找到答案。


它不会回收除非需要。然而我的应用程序(以及根据 StackOverflow 的说法,许多应用程序)由于内存不足异常而被终止。因此,我认为它没有做好回收的工作。 - StackOverflowed
我在Android应用程序中使用了Bitmaps,唯一抛出Out of Memory异常的情况是当我没有正确使用recycle()方法时。我通过使用MAT工具找到了这个问题。 - Amit Deshpande

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接