在Java中何时调用finalize()方法?
我需要知道在在Java中何时调用finalize()方法?,java,methods,garbage-collection,call,finalize,Java,Methods,Garbage Collection,Call,Finalize,我需要知道在JVM中何时调用该方法。我创建了一个测试类,当通过重写finalize()方法调用它时,它会写入一个文件。它没有被执行。有谁能告诉我它不执行的原因吗?当对象即将被垃圾回收时,会调用finalize方法。这可以在垃圾收集合格后的任何时间进行 请注意,对象完全可能永远不会被垃圾收集(因此永远不会调用finalize)。当对象永远不符合gc条件时(因为它在JVM的整个生命周期内都是可访问的),或者在对象符合gc条件到JVM停止运行之间没有垃圾收集实际运行时(这通常发生在简单的测试程序中),
JVM
中何时调用该方法。我创建了一个测试类,当通过重写finalize()
方法调用它时,它会写入一个文件。它没有被执行。有谁能告诉我它不执行的原因吗?当对象即将被垃圾回收时,会调用finalize
方法。这可以在垃圾收集合格后的任何时间进行
请注意,对象完全可能永远不会被垃圾收集(因此永远不会调用finalize
)。当对象永远不符合gc条件时(因为它在JVM的整个生命周期内都是可访问的),或者在对象符合gc条件到JVM停止运行之间没有垃圾收集实际运行时(这通常发生在简单的测试程序中),就会发生这种情况
有一些方法可以告诉JVM在尚未调用它的对象上运行finalize
,但是使用它们也不是一个好主意(该方法的保证也不是很强)
如果您依靠
finalize
来正确操作应用程序,那么您就做错了finalize
应该只用于清理(通常是非Java)资源。这正是因为JVM不保证对任何对象调用finalize
。当对象即将被垃圾回收时,调用finalize
方法。这可以在垃圾收集合格后的任何时间进行
请注意,对象完全可能永远不会被垃圾收集(因此永远不会调用finalize
)。当对象永远不符合gc条件时(因为它在JVM的整个生命周期内都是可访问的),或者在对象符合gc条件到JVM停止运行之间没有垃圾收集实际运行时(这通常发生在简单的测试程序中),就会发生这种情况
有一些方法可以告诉JVM在尚未调用它的对象上运行finalize
,但是使用它们也不是一个好主意(该方法的保证也不是很强)
如果您依靠finalize
来正确操作应用程序,那么您就做错了finalize
应该只用于清理(通常是非Java)资源。这正是因为JVM不能保证在任何对象上调用finalize
Java中何时调用finalize()
方法
finalize方法将在GC检测到对象不再可访问之后,以及在它实际回收对象使用的内存之前调用
- 如果对象从未变得不可访问,则永远不会对其调用
finalize()
- 如果GC没有运行,则可能永远不会调用
。(通常,只有当JVM确定可能有足够的垃圾使其有价值时,GC才会运行。)finalize()
- 在GC确定特定对象不可访问之前,可能需要一个以上的GC周期。(Java GC通常是“世代”收集器…)
- 一旦GC检测到一个对象是不可访问和可终结的,它就会被放入终结队列中。终结通常与普通GC异步进行
finalize()
方法中,应该有一种更好(即更可靠)的方法来执行您试图执行的任何操作
终结的唯一合法用途是清理与应用程序代码丢失的对象相关的资源。即使这样,您也应该尝试编写应用程序代码,以便它不会首先丢失对象。(例如,使用Java 7+try with resources确保始终调用close()
)
我创建了一个测试类,当通过重写finalize()方法调用它时,该类会写入一个文件。它没有被执行。有人能告诉我它不执行的原因吗 很难说,但有几种可能性:
- 对象未被垃圾回收,因为它仍然可以访问
- 对象不会被垃圾收集,因为在测试完成之前GC不会运行
- 该对象由GC找到并放置在终结队列中,但在测试完成之前终结尚未完成
finalize()
方法
finalize方法将在GC检测到对象不再可访问之后,以及在它实际回收对象使用的内存之前调用
- 如果对象从未变得不可访问,则永远不会对其调用
finalize()
- 如果GC没有运行,则可能永远不会调用
。(通常,只有当JVM确定可能有足够的垃圾使其有价值时,GC才会运行。)finalize()
- 在GC确定特定对象不可访问之前,可能需要一个以上的GC周期。(Java GC通常是“世代”收集器…)
- 一旦GC检测到一个对象是不可访问和可终结的,它就会被放入终结队列中。终结通常与普通GC异步进行
protected void finalize() throws Throwable {}
protected void finalize() throws Throwable {
try {
close(); // close open files
} finally {
super.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);
}
while ( true) {
Book novel=new Book(true);
//System.out.println(novel.checkedOut);
//Runtime.getRuntime().runFinalization();
novel.checkIn();
new Book(true);
//System.runFinalization();
System.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
// try-finally block guarantees execution of termination method
Foo foo = new Foo(...);
try {
// Do what must be done with foo
...
} finally {
foo.terminate(); // Explicit termination method
}
class Car {
int maxspeed;
Car() {
maxspeed = 70;
}
protected void finalize() {
// Originally finalize method does nothing, but here we override finalize() saying it to print some stmt
// Calling of finalize is uncertain. Difficult to observe so we force JVM to call it by System.gc(); GarbageCollection
System.out.println("Called finalize method in class Car...");
}
}
class Bike {
int maxspeed;
Bike() {
maxspeed = 50;
}
protected void finalize() {
System.out.println("Called finalize method in class Bike...");
}
}
class Example {
public static void main(String args[]) {
Car c = new Car();
c = null; // if c weren`t null JVM wouldn't be certain it's cleared or not, null means has no future use or no longer in use hence clears it
Bike b = new Bike();
System.gc(); // should clear c, but not b
for (b.maxspeed = 1; b.maxspeed <= 70; b.maxspeed++) {
System.out.print("\t" + b.maxspeed);
if (b.maxspeed > 50) {
System.out.println("Over Speed. Pls slow down.");
}
}
}
}
Called finalize method in class Car...
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51Over Speed. Pls slow down.
52Over Speed. Pls slow down.
53Over Speed. Pls slow down.
54Over Speed. Pls slow down.
55Over Speed. Pls slow down.
56Over Speed. Pls slow down.
57Over Speed. Pls slow down.
58Over Speed. Pls slow down.
59Over Speed. Pls slow down.
60Over Speed. Pls slow down.
61Over Speed. Pls slow down.
62Over Speed. Pls slow down.
63Over Speed. Pls slow down.
64Over Speed. Pls slow down.
65Over Speed. Pls slow down.
66Over Speed. Pls slow down.
67Over Speed. Pls slow down.
68Over Speed. Pls slow down.
69Over Speed. Pls slow down.
70Over Speed. Pls slow down.
public class TestClass {
public TestClass() {
System.out.println("constructor");
}
public void display() {
System.out.println("display");
}
@Override
public void finalize() {
System.out.println("destructor");
}
}
public class TestGarbageCollection {
public static void main(String[] args) {
while (true) {
TestClass s = new TestClass();
s.display();
System.gc();
}
}
}
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();
}
}
}
protected void finalize(){
// This is where the finalization code is entered
}