我在 java 的 system.gc() 和 finalize() 方法之间感到困惑。我们不能强制将垃圾对象收集到 JVM。我们允许在我们的java代码中编写这两种方法,那么如果两者都用于垃圾收集,那么提供两种java垃圾收集方法有什么意义呢?
请告诉我这两种方法的确切工作原理以及它在内部是如何工作的?
我在 java 的 system.gc() 和 finalize() 方法之间感到困惑。我们不能强制将垃圾对象收集到 JVM。我们允许在我们的java代码中编写这两种方法,那么如果两者都用于垃圾收集,那么提供两种java垃圾收集方法有什么意义呢?
请告诉我这两种方法的确切工作原理以及它在内部是如何工作的?
System.gc()
恳请系统执行垃圾收集。Javadoc 说:
运行垃圾收集器。
您无法控制垃圾收集器工作的“难度”。垃圾收集器如何在内部工作是特定于 VM 的,并且本身就是一个研究课题。但通常会有“完整”垃圾收集和一些较小的“增量”收集。所以考虑System.gc
作为一个请求,但不能保证你的对象的垃圾收集会发生。
Object.finalize()
可以重写以指定当给定对象被垃圾收集时要做什么(实际上是在它被垃圾收集之前做什么)。Javadoc 说:
当垃圾收集确定不再有对该对象的引用时,由对象上的垃圾收集器调用。
终结器的经典用途是在对象被垃圾回收时释放系统资源,例如释放文件句柄、临时文件等。
不要在 JVM 退出时使用终结器来执行操作。为此,请使用您注册的关闭挂钩Runtime.getRuntime().addShutdownHook(Thread)
。
System.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()
方法通知JVM垃圾收集器现在可以运行以通过删除未使用的对象来清除内存。根据java文档:
调用 gc 方法表明 Java 虚拟机花费精力回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。
finalize()
方法不会触发垃圾收集器,而是在垃圾收集器销毁对象时调用它。它提供了正确清除对象的说明。
System.gc() 方法垃圾收集由 new 关键字创建的对象,而 finalise() 方法用于垃圾收集不是使用 new 关键字创建的对象。所以,我猜这个答案。你的Q
这里的答案很好,只是想详细说明关于 finalize() 方法的一点:你不应该使用它。它的执行根本无法保证,最终使用 finalize() 会增加性能损失。
正如 Joshua Bloch 在 Effective Java 中所写:
终结器是不可预测的,通常很危险,而且通常是不必要的。永远不要在终结器中做任何时间紧迫的事情。永远不要依赖终结器来更新关键的持久状态。
和:
哦,还有一件事:使用终结器会导致严重的性能损失。在我的机器上,创建和销毁一个简单对象的时间约为 5.6 ns。添加终结器会将时间增加到 2,400 ns。换句话说,使用终结器创建和销毁对象的速度大约慢了 430 倍。
更喜欢使用以下资源终止 try-finally 模式,它可以保证运行:
Bar bar = new Bar(...);
try {
// Your code here
} finally {
bar.releaseResource(); // You implementation. For example close connection
}
垃圾回收用于回收对象分配的内存,Finalize()
由垃圾回收器在回收内存之前调用,该Finalize()
方法主要用于在删除对象之前进行一些操作
有许多包含 finalize() 方法的类,我假设您的意思是 Object 类中的那个。当您希望 Java 的垃圾编译器运行时,您调用 System.gc()。它每隔几分钟就会自行运行,但您可以随时要求它运行。当 gargabe 收集器运行时,它会在每个没有更多引用的对象上调用 finalize() 方法。基本上, System.gc() 清理内存,并使用 finalize() 摆脱单个对象。
通过调用System.gc()
任何类的方法来调用垃圾收集器。但它并不能保证在 jvm 关闭之前所有的无效对象都会被垃圾回收。所以基本上gc()
方法是只收集那些使用 new 关键字创建的对象。由任何其他逻辑创建的对象将在调用垃圾收集器finalize()
之前通过显式调用方法进行gc
垃圾收集。