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

时间:2018-09-17 09:10:25

标签: android garbage-collection

示例:  理想地说,对象是垃圾可收集的(活动更改了方向并强烈引用了丢失的对象),但尚未丢弃。因此,第2行将返回true。在第3行执行时,对象有任何处置方式吗?还是等到完成?

new Thread {

       WeakReference item= new WeakReference(object);

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

2 个答案:

答案 0 :(得分:4)

如果您强烈引用某个对象,则该对象不适合使用GC。

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

另一方面,当您处理弱引用(任何类型)时,首先必须从弱引用包装中取出强引用,然后可以安全地继续使用该强引用(在检查是否存在强引用之后)当然是null)。如果不使用强引用,弱包装器中的对象可能随时消失。

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

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

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

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

答案 1 :(得分:2)

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

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

从Java代码的角度来看,当GC运行时,主线程和所有其他线程都停止了(从调度程序中删除)。但是,并非总是如此。但这取决于VM的实现。但是,您必须始终假定GC运行时所有Java线程(包括主线程)都已停止。

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

  

是的,您的周参考在第二行中可以为空。

**

您的代码可以在第三行中获取NullPointerException。

因为第2行和第3行是两个单独的非原子操作。 GC可能会在执行第2行之后退出,停止执行所有线程,执行垃圾回收,然后继续执行所有线程,从而在第3行发生NullPointerException。