【问题标题】:Android Garbage collector Runs on Main Thread?Android垃圾收集器在主线程上运行?
【发布时间】:2023-04-04 21:59:01
【问题描述】:

示例: 理想情况下,可以说对象是可垃圾回收的(活动改变了方向并且对对象丢失的强引用)但尚未处置。所以第 2 行将返回 true。在第 3 行执行时,有没有办法处理对象?还是等它结束?

new Thread {

       WeakReference item= new WeakReference(object);

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

【问题讨论】:

  • @Sanoop 无关

标签: android garbage-collection


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 你没有回答我的问题。我还说理想情况下,该对象可能是弱引用的,因此如果强引用以某种方式丢失,它的垃圾可回收。
  • 在您的问题中看不到弱引用。如果您有弱引用对象,那么您首先必须从中获取强引用,然后使用该强引用。
  • 我的主要问题是GC是在android进程的主线程上运行还是工作线程?
  • 你的问题没有意义。这与它在哪个线程上运行无关......因为它不是那样工作的。 GC 会停止所有代码执行,直到完成。但它可以随时运行......并且它不会收集任何可以通过任何强引用访问的对象。
  • 请注意,并非每个读者都会查看编辑历史记录,因此以“在空检查和下一行之间没有办法在您的代码中处理对象”作为答案的开头并不是一个好主意”当问题的唯一代码示例是使用弱引用时,对象可以在中间收集垃圾。
【解决方案2】:

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

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

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

所以,为了准确回答您的问题,**

是的,您的星期参考可以在第二行变为空。

**

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

因为第 2 行和第 3 行是两个单独的非原子操作。 GC 可能会在执行第 2 行后启动,停止执行所有线程,进行垃圾收集,然后恢复所有线程,导致在第 3 行发生 NullPointerException。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2011-10-15
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    相关资源
    最近更新 更多