我需要知道什么时候在JVM中调用finalize()方法。我创建了一个测试类,当finalize()方法被重写时写入文件。它没有被执行。有人能告诉我为什么它不能执行吗?
当前回答
最终确定方法是不保证的。当对象符合GC条件时调用此方法。在许多情况下,对象可能不会被垃圾收集。
其他回答
查看Effective Java,第2版第27页。 第7项:避免终结词
终结器是不可预测的,通常是危险的,而且通常是不必要的。永远不要在终结器中做任何时间紧迫的事情。从来没有 依赖终结器更新关键持久状态。
要终止一个资源,请使用try-finally:
// try-finally块保证终止方法的执行 Foo Foo =新的Foo(…); 尝试{ //用foo做必须做的事情 ... }最后{ foo.terminate ();//显式终止方法 }
Java finalize()方法不是析构函数,不应用于处理应用程序所依赖的逻辑。Java规范声明,不能保证在应用程序的生存期内调用finalize方法。
你可能想要的是一个finally和cleanup方法的组合,如:
MyClass myObj;
try {
myObj = new MyClass();
// ...
} finally {
if (null != myObj) {
myObj.cleanup();
}
}
这将正确处理MyClass()构造函数抛出异常时的情况。
在最近与终结器方法搏斗之后(为了在测试期间处理连接池),我不得不说终结器缺少很多东西。使用VisualVM来观察以及使用弱引用来跟踪实际的交互,我发现以下事情在Java 8环境中是正确的(Oracle JDK, Ubuntu 15):
Finalize is not called immediately the Finalizer (GC part) individually owns the reference elusively The default Garbage Collector pools unreachable objects Finalize is called in bulk pointing to an implementation detail that there is a certain phase the garbage collector frees the resources. Calling System.gc() often does not result in objects being finalized more often, it just results in the Finalizer getting aware of an unreachable object more rapidly Creating a thread dump almost always result in triggering the finalizer due to high heap overhead during performing the heap dump or some other internal mechanism Finalization seams to be bound by either memory requirements (free up more memory) or by the list of objects being marked for finalization growing of a certain internal limit. So if you have a lot of objects getting finalized the finalization phase will be triggered more often and earlier when compared with only a few There were circumstances a System.gc() triggered a finalize directly but only if the reference was a local and short living. This might be generation related.
最后认为
最后确定方法是不可靠的,但只能用于一件事。您可以确保在垃圾收集之前关闭或释放对象,从而在正确处理涉及生命结束操作的更复杂生命周期的对象时实现故障安全。这是我能想到的一个值得我们去推翻它的原因。
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
An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static refrences in other words you can say that an object becomes eligible for garbage collection if its all references are null. Cyclic dependencies are not counted as reference so if Object A has reference of object B and object B has reference of Object A and they don't have any other live reference then both Objects A and B will be eligible for Garbage collection. Generally an object becomes eligible for garbage collection in Java on following cases:
该对象的所有引用显式设置为空,例如object = null 对象在块内创建,一旦控件退出该块,引用就会离开作用域。 父对象设置为空,如果一个对象持有另一个对象的引用,并且当您将容器对象的引用设置为空时,子对象或包含对象自动符合垃圾收集的条件。 如果一个对象只有通过WeakHashMap的活动引用,那么它就有资格进行垃圾收集。
推荐文章
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 如何在方法中访问“静态”类变量?
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- c++枚举类可以有方法吗?
- Tomcat:如何查找正在运行的Tomcat版本?
- 使用Moq验证方法调用
- “java”、“javaw”和“javaws”之间有什么区别?