Java中的内存分配 - Android

Sta*_*wed 5 java android garbage-collection java-memory-model

如果我有:

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;
Run Code Online (Sandbox Code Playgroud)

执行此代码后,4个实例中的哪些仍在内存中?我知道.recycle()指示本机代码将所有资源解除分配给该对象,但不能保证何时发生这种情况.

我问的原因是让我们看看以下循环:

Bitmap bitmap = null;

while (true) {
    bitmap = Bitmap.create(...);    
}
Run Code Online (Sandbox Code Playgroud)

我假设这最终会崩溃应用程序(内存不足)?如果是这样,该循环应该如何重写?(如果我使用位图来设置动画并显示更改的状态).

dim*_*414 1

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

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

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

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

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

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