安卓垃圾收集器在主线程上运行?



示例:理想情况下,假设对象是垃圾回收的(活动更改了方向和对丢失对象的强引用(,但尚未释放。因此,第 2 行将返回 true。当执行在第 3 行时,有什么方法可以释放对象?还是等到它完成?

new Thread {
WeakReference item= new WeakReference(object);
void method(){
2      if(item.get()!=null)
3          item.get().getName();
}
}

如果您对某个对象有很强的引用,则该对象不符合 GC 的条件。

强引用对象不可能在 null 检查和下一行之间的代码中被释放......或任何其他行,只要您可以访问该object引用。仅当将该对象引用设置为 null 或将另一个对象分配给该引用时,如果没有指向该对象的其他引用,则可以对前一个对象进行垃圾回收。

另一方面,当你处理弱引用(任何类型的(时,首先你必须从弱引用包装器中获取强引用,然后你可以安全地进一步使用该强引用(当然,在你检查它不是空之后(。如果您不采用强引用,弱包装器中的对象随时可能消失。

错误用法 - 可以在空检查和getName调用之间收集对象

if(item.get()!=null)
item.get().getName();

正确用法 - 为进一步加工提供强有力的参考

Object object = item.get();
if(object!=null)
object.getName();

首先,垃圾收集器不会在你认为的进程主线程上运行。 从操作系统的前景来看,GC 可以在运行应用程序的虚拟机的主线程中运行。或者它可以在新线程上运行。

但是从Java前景来看,GC不会在应用程序的任何线程上运行。运行 GC 的线程既不是您的 Java 主线程,也不是您可以访问的 Java 线程。

从 Java 代码的预期来看,当 GC 运行时,主线程和所有其他线程将停止(从调度程序中删除(。不过,这并不总是正确的。但这取决于 VM 的实现。但是您必须始终假设所有 Java 线程(包括主线程(在 GC 运行时都已停止。

因此,为了准确回答您的问题,**

是的,您的周引用在第二行中可以变为空。

**

你的代码可以在第三行得到一个 NullPointerException。

因为第 2 行和第 3 行是两个独立的非解剖学操作。GC 可能会在执行第 2 行后插入,停止执行所有线程,执行垃圾回收,然后恢复所有线程,导致第 3 行发生 NullPointerException。

最新更新