Java 有没有办法强制finalize()方法
我有以下与Java的finalize方法和垃圾收集相关的问题 有没有一种方法可以让我们强制完成这个方法? 那么,JDK反对以下方法的原因是什么 Runtime.runFinalizersOnExittrue 除了上面的问题,我还在读这篇文章。在本文中,请参阅第5点,作者说在调用垃圾收集器之前调用finalize。那么这件事肯定会发生吗?我的意思是,在执行垃圾收集器方法之前,是否总是调用finalize方法 假设我的堆中有很多垃圾,但垃圾收集器没有执行。那么,这不是JVM的一个坏行为还是一个缺陷呢 既然垃圾收集没有发生,它又如何降低我的应用程序的性能呢Java 有没有办法强制finalize()方法,java,garbage-collection,finalize,Java,Garbage Collection,Finalize,我有以下与Java的finalize方法和垃圾收集相关的问题 有没有一种方法可以让我们强制完成这个方法? 那么,JDK反对以下方法的原因是什么 Runtime.runFinalizersOnExittrue 除了上面的问题,我还在读这篇文章。在本文中,请参阅第5点,作者说在调用垃圾收集器之前调用finalize。那么这件事肯定会发生吗?我的意思是,在执行垃圾收集器方法之前,是否总是调用finalize方法 假设我的堆中有很多垃圾,但垃圾收集器没有执行。那么,这不是JVM的一个坏行为还是一个缺陷呢
finalize方法,因此任何确实需要运行的关键清理代码都应该转到其他地方。您可能应该自己管理这一点—当您处理完一个保存着某些资源的对象后,请执行清理,例如显式地实现一个close方法。出于这些原因,您不应该使用finalize。 除了给出的答案,我给你一些示例代码。这证明,作为一名程序员,您常常无法确保finalize将运行。示例1和5不相关,因为它们很少重要。但3、4和5有时确实如此 请阅读有关幽灵的参考资料。关于finalize的任何问题的答案都不完整,除非提及幻影参考。您可以在非守护进程线程中处理这些问题,并确保JVM在处理所有问题之前不会退出
package com.example.foo;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
/**
* Demonstration of failing finalize-implementations. Just run main, wait and see that it does not
* actually print any messages other than "good bye!", even though there are 5
* <code>System.out.println(...)</code> in the finalize-methods.
*
* <p>
* However, finalize is run even if the instance was not created properly (Exception in
* constructor). This may lead to problems, as the resources to close might not even exist.
*
* <p>
* This answers this question: "Why is there no guarantee that {@link Object#finalize()} is run?"
*
* <p>
* If you want an answer to the question: "Then what can I do to properly use finalize()?" <br/>
* The answer is: Don't! <br/>
* Not just because of the problems presented here. There are actually more problems! <br/>
* Here's a better alternative: http://claude-martin.ch/java-cleanup/
*/
public class SomeClass {
/**
* Finalize of Object is not invoked by some JVMs because it is known to be empty. This is
* relevant if you thought you could use a tools that can intercept invocation of finalize (as in
* aspect-oriented programming).
*/
static final class Finalize1 {
// no finalize
}
/** Class and method not final. */
static class Finalize2 {
@Override
protected void finalize() throws Throwable {
// not final -> extending class doesn't have to call this method.
System.out.println("Finalize2");
}
}
/**
* Finalize allocates new data and fails. GC runs it but you have no guarantee that the JVM can
* run it successfully.
*/
static final class Finalize3 {
@Override
protected void finalize() throws Throwable, OutOfMemoryError {
// What if memory is already running out?
// Chances are high - why else would gc be running?
// Then even a small array could fail:
byte[] bytes = new byte[Integer.MAX_VALUE];
// OutOfMemoryError was thrown!
System.out.println("Finalize3 " + bytes[0]);
// Also not run:
super.finalize();
}
}
static Finalize4 finalize4;
/**
* This is just to show that you, as the author of a class, can not prevent that an instance is
* referenced from a static field. This is also true for all data structures that exist until the
* JVM exits.
*/
static final class Finalize4 {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize4");
}
}
/**
* JVM could end abruptly. Again, you have no control over this when you write a class.
*/
static final class Finalize5 {
@Override
protected void finalize() throws Throwable {
System.out.println("Finalize5");
}
}
/** Runs Garbage Collection. */
static void gc(int n) {
final List<byte[]> list = new LinkedList<>();
try {
while (true)
list.add(new byte[1024 * 1024]);
} catch (OutOfMemoryError e) {
// Now GC is needed...
}
for (int i = 0; i < n; i++) {
System.gc();
try { // Give it time:
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
gc(0); // fills memory
// 1) no finalize implemented:
new Finalize1();
// 2) no call to super.finalize():
new Finalize2() {
private OutputStream resource = new ByteArrayOutputStream();
@Override
protected void finalize() throws Throwable {
// Not calling super.finalize() !
this.resource.close();
}
};
// 3) Failing finalize:
new Finalize3();
// 4) static reference:
finalize4 = new Finalize4();
// Now let's try to get rid of them:
gc(20);
// 5) No time:
new Finalize5();
System.out.println("good bye!");
System.exit(0);
}
}
目标.最后确定;可以通过强制为要销毁的对象的实例运行finalize来销毁该对象。