15

我在 java 的 system.gc() 和 finalize() 方法之间感到困惑。我们不能强制将垃圾对象收集到 JVM。我们允许在我们的java代码中编写这两种方法,那么如果两者都用于垃圾收集,那么提供两种java垃圾收集方法有什么意义呢?

请告诉我这两种方法的确切工作原理以及它在内部是如何工作的?

4

8 回答 8

13

System.gc()恳请系统执行垃圾收集。Javadoc 说:

运行垃圾收集器。

您无法控制垃圾收集器工作的“难度”。垃圾收集器如何在内部工作是特定于 VM 的,并且本身就是一个研究课题。但通常会有“完整”垃圾收集和一些较小的“增量”收集。所以考虑System.gc作为一个请求,但不能保证你的对象的垃圾收集会发生。

Object.finalize()可以重写以指定当给定对象被垃圾收集时要做什么(实际上是在它被垃圾收集之前做什么)。Javadoc 说:

当垃圾收集确定不再有对该对象的引用时,由对象上的垃圾收集器调用。

终结器的经典用途是在对象被垃圾回收时释放系统资源,例如释放文件句柄、临时文件等。

不要在 JVM 退出时使用终结器来执行操作。为此,请使用您注册的关闭挂钩Runtime.getRuntime().addShutdownHook(Thread)

于 2012-04-17T06:28:19.617 回答
2

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.
于 2012-04-17T06:28:58.803 回答
1

system.gc()方法通知JVM垃圾收集器现在可以运行以通过删除未使用的对象来清除内存。根据java文档:

调用 gc 方法表明 Java 虚拟机花费精力回收未使用的对象,以使它们当前占用的内存可用于快速重用。当控制从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。

finalize()方法不会触发垃圾收集器,而是在垃圾收集器销毁对象时调用它。它提供了正确清除对象的说明。

于 2012-04-17T06:34:39.507 回答
1

System.gc() 方法垃圾收集由 new 关键字创建的对象,而 finalise() 方法用于垃圾收集不是使用 new 关键字创建的对象。所以,我猜这个答案。你的Q

于 2015-11-16T16:12:27.390 回答
1

这里的答案很好,只是想详细说明关于 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
}
于 2016-11-09T15:46:30.910 回答
0

垃圾回收用于回收对象分配的内存,Finalize()由垃圾回收器在回收内存之前调用,该Finalize()方法主要用于在删除对象之前进行一些操作

于 2012-04-17T06:29:24.933 回答
0

有许多包含 finalize() 方法的类,我假设您的意思是 Object 类中的那个。当您希望 Java 的垃圾编译器运行时,您调用 System.gc()。它每隔几分钟就会自行运行,但您可以随时要求它运行。当 gargabe 收集器运行时,它会在每个没有更多引用的对象上调用 finalize() 方法。基本上, System.gc() 清理内存,并使用 finalize() 摆脱单个对象。

于 2012-04-17T06:29:40.197 回答
0

通过调用System.gc()任何类的方法来调用垃圾收集器。但它并不能保证在 jvm 关闭之前所有的无效对象都会被垃圾回收。所以基本上gc()方法是只收集那些使用 new 关键字创建的对象。由任何其他逻辑创建的对象将在调用垃圾收集器finalize()之前通过显式调用方法进行gc垃圾收集。

于 2016-12-25T04:16:30.520 回答