运行时gc实际上做了什么以及导致此输出的原因是什么?

时间:2017-03-04 08:06:05

标签: java garbage-collection jvm

是否强制线程调度程序获取执行gc线程,或者它只是以gc线程的优先级播放?

class Test1
{
public static void main(String[] args)
{
Test1 test = new Test1();
test = null;
Runtime.getRuntime().gc();
System.out.println("in main after gc...");


public void finalize()
{
 System.out.println("in finalize method...");

}
}

输出可能性1: 在最终方法中...... 在主要的gc之后...

输出可能性2: 在主要的gc之后...... 在最终确定方法......

输出可能性1:解释: 此输出可能是因为“Runtime.getRuntime()。gc()”使gc线程执行哪个打印的第一行,然后拾取主线程并打印第二行。

输出可能性2:解释: 导致此输出的原因是什么? 是因为“Runtime.getRuntime()。gc()”使gc线程的优先级高,以便主线程持续一段时间后接收到gc线程?

1 个答案:

答案 0 :(得分:2)

  

Runtime.gc()实际上做了什么?

理论上它可以做各种各样的事情。例如:

  • 它可能导致垃圾收集器立即运行,暂停当前线程直到它完成。
  • 它可能一无所获。
  • 它可能会做点什么;例如有机会触发GC,或者提高GC线程的优先级。

规范中有足够的(故意的)歧义,无法说明gc()调用是否会导致收集特定对象。当然,不是所有可以运行应用程序的平台/所有平台。

您似乎对finalize的时间安排感兴趣/担心。 "坏消息"即使你知道特定的gc()会发现给定的对象无法访问,你也无法确定它会在gc()调用完成之前完成。

事实上,当一个典型的HotSpot GC发现一个可终结的无法访问的对象时,它会将其排队,以便在GC循环之后完成。该对象尚未被删除。

因此,上述的实际输出可能以下任何一项:

  1. 一条消息:

      in main after gc
    
  2. 两条消息:

      in main after gc
      in finalize method
    
  3. 另一个订单中的两条消息

      in finalize method
      in main after gc
    
  4. 如果忽略gc()调用,或者JVM在JVM处理完成队列之前退出,则会发生第一种情况。

    案例二是当前生成JVM的最可能行为。

    如果在此gc()调用发生之前其他内容触发了GC,则可能发生第三种情况。它也可能发生在(假设的)Java实现中,其中最终化与垃圾收集同步发生。