我需要知道什么时候在JVM中调用finalize()方法。我创建了一个测试类,当finalize()方法被重写时写入文件。它没有被执行。有人能告诉我为什么它不能执行吗?
当前回答
试着运行这个程序,以便更好地理解
public class FinalizeTest
{
static {
System.out.println(Runtime.getRuntime().freeMemory());
}
public void run() {
System.out.println("run");
System.out.println(Runtime.getRuntime().freeMemory());
}
protected void finalize() throws Throwable {
System.out.println("finalize");
while(true)
break;
}
public static void main(String[] args) {
for (int i = 0 ; i < 500000 ; i++ ) {
new FinalizeTest().run();
}
}
}
其他回答
Finalize()在垃圾收集之前被调用。当对象超出作用域时,不调用它。这意味着您无法知道finalize()何时甚至是否会执行。
例子:
如果你的程序在垃圾回收发生之前结束,finalize()将不会执行。因此,它应该被用作备份过程,以确保其他资源的正确处理,或用于特殊用途的应用程序,而不是作为您的程序在其正常运行中使用的手段。
正如在https://wiki.sei.cmu.edu/confluence/display/java/MET12-J.+Do+not+use+finalizers上指出的那样,
There is no fixed time at which finalizers must be executed because time of execution depends on the Java Virtual Machine (JVM). The only guarantee is that any finalizer method that executes will do so sometime after the associated object has become unreachable (detected during the first cycle of garbage collection) and sometime before the garbage collector reclaims the associated object's storage (during the garbage collector's second cycle). Execution of an object's finalizer may be delayed for an arbitrarily long time after the object becomes unreachable. Consequently, invoking time-critical functionality such as closing file handles in an object's finalize() method is problematic.
Java allows objects to implement a method called finalize() that might get called. finalize() method gets called if the garbage collector tries to collect the object. If the garbage collector doesn't run, the method doesn't get called. If the garbage collector fails to collect the object and tries to run it again, the method doesn't get called in the second time. In practice, you are highly unlikely to use it in real projects. Just keep in mind that it might not get called and that it definitely won't be called twice. The finalize() method could run zero or one time. In the following code, finalize() method produces no output when we run it since the program exits before there is any need to run the garbage collector.
源
Finalize将打印出类创建的计数。
protected void finalize() throws Throwable {
System.out.println("Run F" );
if ( checkedOut)
System.out.println("Error: Checked out");
System.out.println("Class Create Count: " + classCreate);
}
main
while ( true) {
Book novel=new Book(true);
//System.out.println(novel.checkedOut);
//Runtime.getRuntime().runFinalization();
novel.checkIn();
new Book(true);
//System.runFinalization();
System.gc();
如你所见。下面的输出显示了类计数为36时第一次执行的gc。
C:\javaCode\firstClass>java TerminationCondition
Run F
Error: Checked out
Class Create Count: 36
Run F
Error: Checked out
Class Create Count: 48
Run F
JDK 18的最新消息
根据openjdk 18发布的JEPS 421, finalize()方法的终结和功能将被标记为已弃用(forRemoval=true),这意味着永久删除将在jdk 18之后的某个后续版本中进行。
从jdk 18开始,一个新的命令行选项——finalization=disabled禁用了所有地方的终结机制,甚至是jdk内部的声明。
这也与这里的这个问题有关,因为它被计划删除的原因是它包含的一些主要缺陷。其中一个缺陷是,从一个对象变得不可访问到调用它的终结器之间可能会经过很长一段时间。GC也不能保证任何终结器将被调用,这也是事实。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap