当调用System.gc()或finalize()方法时,Java虚拟机(JVM)内部会发生什么?
这是否真正回收了垃圾或降低了性能?
当调用System.gc()或finalize()方法时,Java虚拟机(JVM)内部会发生什么?
这是否真正回收了垃圾或降低了性能?
System.gc()
,垃圾回收器会运行,正如其名称所示。在这一点上,当对象真正被移除时,在它们消失之前,将调用这些对象的finalize()
。or
"。它是垃圾收集和性能降低。gc
,因为它可以为您提供非常好的服务。但是,在某些使用场景中,您可能希望在特定时间点摆脱大量对象;那么这是可行的。System.gc() 会清理内存,并使用 finalize() 来处理单个对象。
finalize()是一种在对象准备进行垃圾回收(当对象没有强引用时)之前执行最后一段代码的方法。
那么它应该在什么情况下使用呢? 只有在以下两种情况下:
除了上述两种情况外,永远不要使用它。要理解原因,我们需要了解对象的功能和生命周期。
介绍:有一个单独的守护线程称为finalizer线程,负责调用finalize()方法。Finalization队列是放置准备调用finalize()方法的对象的队列。
当创建一个对象时,JVM会检查该对象是否有finalize()方法。如果有,则它在内部记录该特定对象具有finalize()方法。Basically finalize() method is only called once.
那么上述循环有什么问题呢?
从(1)来看,它需要额外的时间来创建对象。在Java中,内存分配比malloc/calloc等快5倍到10倍。所有节省下来的时间都会在将对象记录在表格中的过程中丢失。我曾经尝试过。在循环中创建100000个对象,并测量程序在两种情况下终止所需的时间:一种是没有finalize(),另一种是有finalize()。发现后者要快20%。
从(2b)来看:内存泄漏和饥饿。如果队列中的对象引用了大量的内存资源,那么除非该对象准备进行GC,否则所有这些对象都不会被释放。如果所有对象都是重量级对象,则可能会出现短缺。
从(2b)来看:因为finalize()只被调用一次,如果在finalize()中有对“this”对象的强引用,那么下一次对象的finalize()就永远不会被调用,因此可能会使对象处于不一致状态。
如果在finalize()中抛出异常,则会被忽略。
由于您无法控制GC何时被调用,因此您不知道何时调用finalize()。有时,您可能正在打印finalize()中的值,但输出从未显示,因为在调用finalize()时,您的程序可能已经终止。
因此,请避免使用它。相反,创建一个名为dispose()的方法,该方法将关闭必要的资源或进行最终日志记录等。 有关此完整帖子的详细信息。我希望这可以澄清。
是的,System.gc(); 如果需要的话会触发finalize()方法。 public class TestGarbageCollection {
public static void main(String[] args) {
while (true) {
TestClass s = new TestClass();
s.display();
System.gc();
}
}
}
公共类测试类 {
public TestClass() {
System.out.println("constructor");
}
public void display() {
System.out.println("display");
}
@Override
public void finalize() {
System.out.println("destructor");
}
}
这将触发finalize()方法。无论您是否覆盖本地类或对象的finalize方法,都将调用finalize方法。
System.gc
并不能保证立即调用垃圾收集器以释放内存。这只是建议!!! - Arun Kumar