java - Java 中的内存分配 - Android

标签 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;

执行此代码后,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/

相关文章:

java - 无法实例化接收器 com.google.firebase.iid.FirebaseInstanceIdReceiver : java. lang.ClassNotFoundException:

java - 仅在 Spring boot 2.0.0 响应时执行 GenericFilterBean

java - AWSSDK V2 Java SES 发送电子邮件 - AmazonSimpleEmailService 无法解析

Android:错误:不能从静态上下文引用非静态类型变量 T

javascript - 将对象转换为 JSON 字符串并将其置空

java - Jsoup:尝试访问页面时出现错误 307

android - 弹出后堆栈后,我的 fragment 没有被垃圾收集

android - IOT-在本地网络上查找设备的正确方法

java - 识别未被垃圾收集的对象的更好方法?

`onload` 事件的 JavaScript 对象/回调生命周期