我对java的system.gc()和finalize()方法感到困惑。 我们无法强制JVM收集垃圾对象。我们可以在java代码中编写这两种方法,如果两者都用于垃圾回收,那么Java提供两种垃圾回收方法的意义是什么?
请告诉我这两种方法的精确工作方式以及内部如何工作。
我对java的system.gc()和finalize()方法感到困惑。 我们无法强制JVM收集垃圾对象。我们可以在java代码中编写这两种方法,如果两者都用于垃圾回收,那么Java提供两种垃圾回收方法的意义是什么?
请告诉我这两种方法的精确工作方式以及内部如何工作。
System.gc()
会请求系统进行垃圾回收。Javadoc指出:
运行垃圾回收器。
你无法控制垃圾回收器的“工作强度”。垃圾回收器内部的工作方式是与VM有关的,并且是一个研究课题。但通常会进行一些较小的“增量”回收和一些“完全”的垃圾回收。因此,请将System.gc
视为请求,但不能保证对象的垃圾回收一定会发生。
Object.finalize()
可以被覆盖以指定在给定对象被垃圾回收时要执行的操作(实际上是在它被垃圾回收之前要执行的操作)。Javadoc指出:
当GC确定不再有对该对象的引用时,由垃圾回收器在对象上调用。
finalizer的经典用途是在对象被垃圾回收时释放系统资源,例如释放文件句柄、临时文件等。
请勿使用finalizer来在JVM退出时执行操作。为此,请使用通过Runtime.getRuntime().addShutdownHook(Thread)
注册的关闭挂钩。
System.gc()
的调用中的任何“友好”或“礼貌”都是无感知的。如果你粗鲁地进行调用,它也会以同样的方式工作 :-) - Stephen CSystem.gc()
强制执行垃圾回收,而您对象的 Finalize()
方法定义了垃圾回收器在收集此特定对象时应执行的操作。
简单来说,就是这样:
class MyClass {
public UnmanagedResource resource;
void Finalize() {
FreeUnmanagedResource(resource);
}
}
MyClass[] data = new MyClass[1000];
for(int i=0; i<1000; i++) {
data[i] = new MyClass();
}
//do some work
data = null;
System.gc(); //Note that it doesn't guarantee you that all MyClass instances will be actually collected at this point.
System.gc()
绝对不会强制运行 GC。它只是通知 GC 应用程序想要运行 GC,但不能保证任何事情会发生。 - ctomeksystem.gc()
方法通知JVM可以运行垃圾回收器来通过删除未使用的对象来清除内存。根据Java文档:
调用gc方法建议Java虚拟机花费精力回收未使用的对象,以便使它们当前占用的内存可用于快速重用。当从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间。
finalize()
方法不会触发垃圾回收器,而是在垃圾回收器即将销毁对象时调用。它提供了清除对象的指令。
System.gc()方法用于垃圾回收由new关键字创建的对象,而finalize()方法用于垃圾回收未使用new关键字创建的对象。所以,我猜这回答了你的问题。
Bar bar = new Bar(...);
try {
// Your code here
} finally {
bar.releaseResource(); // You implementation. For example close connection
}
垃圾回收用于回收对象的已分配内存,Finalize()
在回收内存之前被垃圾回收器调用,Finalize()
方法通常用于在删除对象之前执行某些操作。
有许多包含finalize()方法的类,我假设您指的是Object类中的方法。当您想要运行Java的垃圾编译器时,可以使用System.gc()。它每隔几分钟就会自动运行,但您也可以在需要时调用它。当垃圾收集器运行时,它会对每个没有引用的对象调用finalize()方法。基本上,System.gc()会清理内存并使用finalize()来消除单个对象。
垃圾收集器是通过在任何类上调用System.gc()
方法来调用的。但它不能保证在jvm关闭之前所有被置空的对象都将被垃圾收集。因此,gc()
方法只会垃圾收集使用new关键字创建的对象。使用其他逻辑创建的对象将在调用gc
调用垃圾收集器之前显式调用finalize()
方法进行垃圾收集。