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