java中finalize()方法的使用

我看了例程但是不是很明白
希望有前辈给我说一下,最好结合一个简单的例子
谢谢,我分不多,全部给你

设计一个对象重生的代码来演示,如下:

具体解析如下:

为方便起见, 把a,b两个变量所指的内存空间就叫做a和b。

A a = new A(new B("allen" , 20))  ; //此时a和b都是reachable, unfinalized状态。

a = null ;

这之后, a和b的状态会在某一个时刻变成unreachable, unfinalized或者a和b直接变成f-reachable, unfianlized。

然后在某个时刻,GC检测到a和b处于unfinalized状态,就将他们添加到F-queue,并将状态改为f-reachable finalizable。

之后分两种情况:

1、 GC从F-queue中首先取出a, 并被某个线程执行了finalize(), 也就相当于被某个活动的线程持有, a状态变成了reachable, finalized.。

此时由于a被c对象所引用,所以之后不会变成unreachable finalized而被销毁(重生) 与此同时,b由于一直被a所引用,,所以b的状态变成了reachable, finalizable.。

然后在某个时刻被从F-queue取出, 变成reachable, finalized状态。

2、GC从F-queue中首先取出b,并被某个线程执行了finalize(), 状态变成reachable finalized. 然后a也类似, 变成reachable finalized状态, 并被c引用,重生。

扩展资料:

尽量避免使用finalize():

1、finalize()不一定会被调用, 因为java的垃圾回收器的特性就决定了它不一定会被调用。

2、就算finalize()函数被调用, 它被调用的时间充满了不确定性, 因为程序中其他线程的优先级远远高于执行finalize()函数线程的优先级。也许等到finalize()被调用, 数据库的连接池或者文件句柄早就耗尽了。

3、如果一种未被捕获的异常在使用finalize方法时被抛出,这个异常不会被捕获,finalize方法的终结过程也会终止,造成对象出于破坏的状态。被破坏的对象又很可能导致部分资源无法被回收, 造成浪费。

4、finalize()函数和垃圾回收器的运行本身就要耗费资源, 也许会导致程序的暂时停止。

参考资料:

百度百科--finalize

温馨提示:内容为网友见解,仅供参考
第1个回答  2018-12-07

finalize方法是Object提供的的实例方法,使用规则如下:

当对象不再被任何对象引用时,GC会调用该对象的finalize()方法

finalize()是Object的方法,子类可以覆盖这个方法来做一些系统资源的释放或者数据的清理

可以在finalize()让这个对象再次被引用,避免被GC回收;但是最常用的目的还是做cleanup

Java不保证这个finalize()一定被执行;但是保证调用finalize的线程没有持有任何user-visible同步锁。

在finalize里面抛出的异常会被忽略,同时方法终止。

当finalize被调用之后,JVM会再一次检测这个对象是否能被存活的线程访问得到,如果不是,则清除该对象。也就是finalize只能被调用一次;也就是说,覆盖了finalize方法的对象需要经过两个GC周期才能被清除。

扩展资料:

举例:

//FileInputStream.java

protected void finalize() throws IOException {

if (guard != null) {

guard.warnIfOpen();

}

if ((fd != null) &&  (fd != FileDescriptor.in)) {

close();

}

}

在finalize里面做资源释放的操作。

参考资料:百度百科—finalize

本回答被网友采纳
第2个回答  2009-11-03
finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。

对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。

finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。

finalize就是一个对象的遗书,你把一个对象给杀了总的让他说点什么把。只不过你要注意finalize是垃圾回收启动来清理对象才来调用的,就算自己掉这个方法这个对象也不会就从内存消失的,代码楼上就行。还有就是这个遗书可以把自己复活,另外如果在这个方法抛异常会导致此对象的终结操作停止,这两种都是死而复生的手段。
第3个回答  2009-11-03
类的Finalize方法,可以告诉垃圾回收器应该执行的操作,该方法从Object类继承而来。在从堆中永久删除对象之前,垃圾回收器调用该对象的Finalize方法。注意,无法确切地保证垃圾回收器何时调用该方法,也无法保证调用不同对象的方法的顺序。即使一个对象包含另一个对象的引用,或者在释放一个对象很久以前就释放了另一个对象,也可能会以任意的顺序调用这两个对象的Finalize方法。如果必须保证采用特定的顺序,则必须提供自己的特有清理方法。

可从本书支持网站下载的示例程序GarbageCollection使用下列代码演示了Finalize方法:

Public Class Form1 Public Running As Boolean Private Class Junk Public MyForm As Form1 Public Sub New(ByVal my_form As Form1) MyForm = my_form End Sub ' Garbage collection started. Protected Overrides Sub Finalize() ' Stop making objects. MyForm.Running = False End Sub End Class ' Make objects until garbage collection starts. Private Sub btnCreateObjects_Click() Handles btnCreateObjects.Click Running = True Dim new_obj As Junk Dim max_i As Long For i As Long = 1 To 100000 new_obj = New Junk(Me) If Not Running Then max_i = i Exit For End If Next i MessageBox.Show("Allocated " & max_i.ToString & " objects") End Sub End Class Form1类先定义公有变量Running,然后定义Junk类,该类包含引用Form1类的变量。Junk类的构造函数保存创建它的Form1对象的引用,它的Finalize方法设置Form1对象的Running值为False。

参考资料:http://book.51cto.com/art/200910/155868.htm

本回答被提问者采纳
第4个回答  2009-11-03
public class ObjectGc {
public ObjectGc() {}

public static void main(String [] args) {
ObjectGc og = new ObjectGc();
//很明显,og没有存在的意义了
og = null;
//由于垃圾回收是不定时的,我们还是手动回收看看吧
System.gc();
}
//当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
protected void finalize() {
System.out.println("我已经被垃圾回收器回收了...");
}
}
相似回答