Raj*_*r J 320 java methods garbage-collection finalize call
我需要知道何时finalize()
调用该方法JVM
.我创建了一个测试类,当finalize()
通过覆盖它来调用方法时,该测试类会写入文件.它没有被执行.谁能告诉我它没有执行的原因?
Joa*_*uer 369
finalize
当对象即将收集垃圾时调用该方法.这可以在它有资格进行垃圾收集之后的任何时间.
请注意,对象永远不会被垃圾收集(因此finalize
永远不会被调用).当对象从来就符合GC(因为它是可到达通过JVM的整个生命周期),或在没有垃圾收集的时间之间实际运行对象资格和JVM停止运行的时间(这往往与简单的时就会发生这种情况测试程序).
有一些方法可以告诉JVM finalize
在尚未调用的对象上运行,但使用它们也不是一个好主意(该方法的保证也不是很强).
如果你依赖于finalize
你的应用程序的正确操作,那么你做错了什么.finalize
应该只用于清理(通常是非Java)资源.而这正是因为JVM不能保证finalize
在任何对象上调用它.
小智 268
一般来说,最好不要依赖finalize()
任何清理等.
根据Javadoc(它值得一读),它是:
当垃圾收集确定没有对该对象的更多引用时,由对象上的垃圾收集器调用.
正如Joachim指出的那样,如果对象始终可访问,这可能永远不会发生在程序的生命周期中.
此外,垃圾收集器不保证在任何特定时间运行.一般来说,我想说的finalize()
可能不是一般使用的最佳方法,除非你需要它具体的东西.
Xpi*_*itO 71
Run Code Online (Sandbox Code Playgroud)protected void finalize() throws Throwable {}
- 每个类都
finalize()
从java.lang.Object 继承该方法- 垃圾收集器在确定不再存在对该对象的引用时调用该方法
- Object finalize方法不执行任何操作,但可以被任何类覆盖
- 通常应该重写它以清理非Java资源,即关闭文件
如果覆盖
finalize()
它是一个很好的编程习惯,使用try-catch-finally语句并始终调用super.finalize()
.这是一种安全措施,可确保您不会无意中错过关闭对象调用类所使用的资源Run Code Online (Sandbox Code Playgroud)protected void finalize() throws Throwable { try { close(); // close open files } finally { super.finalize(); } }
finalize()
垃圾收集期间抛出的任何异常都会停止终结,但会被忽略finalize()
永远不会在任何对象上运行多次
引用自:http://www.janeg.ca/scjp/gc/finalize.html
您还可以查看这篇文章:
rsp*_*rsp 25
Java finalize()
方法不是析构函数,不应该用于处理应用程序所依赖的逻辑.Java规范声明无法保证finalize
在应用程序的实时时间内完全调用该方法.
您可能想要的是组合finally
和清理方法,如:
MyClass myObj;
try {
myObj = new MyClass();
// ...
} finally {
if (null != myObj) {
myObj.cleanup();
}
}
Run Code Online (Sandbox Code Playgroud)
Hao*_*eng 20
查看Effective Java,第2版第27页. 第7项:避免使用终结器
终结器是不可预测的,通常是危险的,并且通常是不必要的.永远不要在终结者中做任何时间关键的事情.从不依赖终结器来更新关键持久状态.
要终止资源,请使用try-finally:
Run Code Online (Sandbox Code Playgroud)// 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 }
Ste*_*n C 16
finalize()
Java中调用的方法是什么时候?
在GC检测到对象不再可访问之后,以及在实际回收对象使用的内存之前,将调用finalize方法.
如果一个对象永远不会无法访问,finalize()
将永远不会被调用.
如果GC未运行,则finalize()
可能永远不会被调用.(通常情况下,只有当JVM确定可能存在足够的垃圾才能使其值得时,GC才会运行.)
在GC确定特定对象无法访问之前,可能需要多个GC周期.(Java GCs通常是"世代"收藏家...)
一旦GC检测到一个对象无法访问并可终结,它就会被置于一个终结队列中.终结通常与普通GC异步发生.
(JVM规范,实际上是允许一个JVM来从未运行终结......只要它不回收对象使用的空间.这是这种方式实现一个JVM将被削弱/没用,但这种行为是"允许" .)
结果是依靠最终化来完成必须在确定的时间范围内完成的事情是不明智的.根本不使用它们是"最佳实践".应该有一种更好(即更可靠)的方式来做你在该finalize()
方法中尝试做的任何事情.
完成的唯一合法用途是清理与应用程序代码丢失的对象相关联的资源.即使这样,您也应该尝试编写应用程序代码,以便它不会丢失对象.(例如,使用Java 7+ try-with-resources确保close()
始终调用...)
我创建了一个测试类,当通过覆盖它调用finalize()方法时,该测试类会写入文件.它没有被执行.谁能告诉我它没有执行的原因?
很难说,但有一些可能性:
tec*_*109 10
由于JVM调用finalize()方法存在不确定性(不确定是否会执行被覆盖的finalize()),出于研究目的,观察调用finalize()时发生的事情的更好方法是强制JVM通过命令调用垃圾回收System.gc()
.
具体来说,当对象不再使用时调用finalize().但是当我们试图通过创建新对象来调用它时,它的调用并不确定.因此,对于把握我们创建了一个null
对象c
,这显然是没有前途的使用,因此我们看到物体c
的敲定电话.
例
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.");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
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.
Run Code Online (Sandbox Code Playgroud)
注意 - 即使在打印到70之后并且在程序中没有使用对象b之后,仍然存在由JVM清除b的不确定性,因为不打印"在Bike类中调用最终方法...".
小智 5
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);
}
Run Code Online (Sandbox Code Playgroud)
主要
while ( true) {
Book novel=new Book(true);
//System.out.println(novel.checkedOut);
//Runtime.getRuntime().runFinalization();
novel.checkIn();
new Book(true);
//System.runFinalization();
System.gc();
Run Code Online (Sandbox Code Playgroud)
如你看到的.以下输出显示gc在班级计数为36时第一次执行.
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
470800 次 |
最近记录: |