如果我有:
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() 指示 native 代码将所有资源释放给该对象,但无法保证何时发生。
我问的原因是让我们看看下面的循环:
Bitmap bitmap = null;
while (true) {
bitmap = Bitmap.create(...);
}
我假设这最终会使应用程序崩溃(内存不足)?如果是这样,应该如何重写这个循环? (如果我使用位图来动画和显示更改的状态)。
最佳答案
Java(以及 Android 的扩展)使用异步 garbage collection清理分配的内存。收集器在后台运行,释放它可以释放的内存。这意味着您在任何时间点都不能保证*有多少无法访问的对象已被清理,还有哪些仍未完成。
在您的第一个代码块完成执行后,所有四个 Bitmap
对象可能仍然存在于堆中,但在某个时候垃圾收集器将运行,确定它们都不再可访问,并释放它们的相关内存。
第二个代码块也是如此;一些任意数量的对象仍然存在于堆中,即使它们不再可访问,但是 GC 将尽最大努力在这种情况下清理它们。在实践中,GC 非常擅长清理此类短暂的对象,因此它甚至可以跟上您的循环(但这并不能保证)。
JVM/ART 将尽最大努力避免 OutOfMemory
情况,包括积极的最后一搏垃圾收集,以尝试回收任何可能的内存以保持应用程序运行。因此,您的第二个循环不太可能导致任何问题,但您可以很容易地进行测试。
希望您不是真的创建并立即丢弃数以千计的 Bitmap
对象;大概它们至少被使用了一段时间,在此期间您不只是创建更多实际上未使用的 Bitmap
(如果是这样,那就是您的问题)。
* 有技巧的,比如用PhantomReference
,它确实可以让您监视垃圾收集的状态,但是这些会给 GC 带来更多负担,因此通常不是一个好主意,也不是必需的。
关于java - Java 中的内存分配 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12019852/