2017-03-04 65 views
0

它是否强制线程调度程序拿起gc线程执行,或者它只是简单地使用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: 在finalize方法... 在GC后主...

输出可能性2: 在主GC之后... 在finalize方法...

输出可能性1:说明: 此输出可能是由于“Runtime.getRuntime().gc()”使gc线程执行哪条打印的第一行,之后主线程被拾取并打印第二行。

输出可能性2:解释: 是什么导致这个输出? 是否因为“Runtime.getRuntime().gc()”使gc线程的优先级为高,以便主线程在gc线程被拾取后持续一段时间?

+0

我认为它是特定于实现的,但我认为gc“建议”垃圾回收。一个通常被忽略的建议(因为JVM知道它在做什么,并告诉它什么时候进行垃圾收集通常是一个糟糕的主意) –

+0

没有保证何时调用finalize,因此无论调用gc还是不调用gc –

+2

除了作为调试工具外,您不应该使用终结器。你不能依靠他们。 –

回答

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 
    

情况下,如果任一GC()调用将被忽略一个会发生,或210条

  • 两个消息如果JVM退出JVM处理终止队列之前。

    第二种情况是当前代JVM的最可能行为。

    如果在这个gc()调用发生之前其他东西触发GC,则可能发生情况三。它也可能出现在一个(假设的)Java实现中,在这个实现中,最终确定与垃圾收集同步发生。

  • 相关问题