/** * Ensures that the <code>close</code> method of this file input stream is * called when there are no more references to it. * * @exception IOException if an I/O error occurs. * @see java.io.FileInputStream#close() */ protected void finalize() throws IOException { if (fd != null) { if (fd != fd.in) { close(); } } } 这个是FileInputStream的finalize代码。不过这两个方法如果不是非常清楚,不建议使用。:)
class MyTest { public static void main(String []args) { for(int i=0;i<4;i++) { MyClass mc=new MyClass(); }
System.gc(); //将该行注释,比较前后运行差别。 JRE在内存不足时才调用该方法.
}
} class MyClass { static int count=0; static int cnt=0; MyClass() { count++; System.out.println("The object "+count+" is created."); } protected void finalize() { cnt++; System.out.println("The object "+cnt+" is released."); } }
通过Test1的输出可以看到,对象被回收时几乎是随机的、无法预料的。对Test1改进成为Test2,我们可以看到,在对象销毁时,显式进行垃圾 回收的运行顺序了,同时会发现这个程序运行得很慢。Test1.java public class Test1 { public static void main(String[] args) { for (int i = 0; i < 10000; i++) { FinalizeTest ft = new FinalizeTest(i); System.out.println(ft.getId() + " 被创建了!"); } } }Test2.java public class Test2 { public static void main(String[] args) { for (int i = 0; i < 50; i++) { System.gc(); FinalizeTest ft = new FinalizeTest(i); System.out.println(ft.getId() + " 被创建了!"); } System.gc(); } }FinalizeTest.java public class FinalizeTest { private int id; public FinalizeTest(int id) { this.id = id; } public int getId() { return id; } protected void finalize() throws Throwable { System.out.println(" " + id + " 被回收了!"); } }
* Ensures that the <code>close</code> method of this file input stream is
* called when there are no more references to it.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
protected void finalize() throws IOException {
if (fd != null) {
if (fd != fd.in) {
close();
}
}
}
这个是FileInputStream的finalize代码。不过这两个方法如果不是非常清楚,不建议使用。:)
{
public static void main(String []args)
{
for(int i=0;i<4;i++)
{
MyClass mc=new MyClass();
}
System.gc(); //将该行注释,比较前后运行差别。 JRE在内存不足时才调用该方法.
}
}
class MyClass
{
static int count=0;
static int cnt=0;
MyClass()
{
count++;
System.out.println("The object "+count+" is created.");
}
protected void finalize()
{
cnt++;
System.out.println("The object "+cnt+" is released.");
}
}
gc
public static void gc()运行垃圾回收器。
调用 gc 方法暗示着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。当控制权从方法调用中返回时,虚拟机已经尽最大努力从所有丢弃的对象中回收了空间。 调用 System.gc() 实际上等效于调用: Runtime.getRuntime().gc()
另请参见:
Runtime.gc()
finalize
protected void finalize()
throws Throwable当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。
finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。 Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。 Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。 在启用某个对象的 finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。 对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。 finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。
抛出:
Throwable - 此方法抛出的 Exception
基于JAVA垃圾处理的特殊性,无法确定析构的时机
JAVA对象的终结由GC负责,没有很特别的理由,不需要过渡干涉
不一定马上会被虚拟机处理,在内存很紧张的情况下,可以使用这个方法来强制让
虚拟机进行垃圾回收,但是这样做的效率是低下的,执行时会花掉一些时间。
回收的运行顺序了,同时会发现这个程序运行得很慢。Test1.java
public class Test1 {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
FinalizeTest ft = new FinalizeTest(i);
System.out.println(ft.getId() + " 被创建了!");
}
}
}Test2.java
public class Test2 {
public static void main(String[] args) {
for (int i = 0; i < 50; i++) {
System.gc();
FinalizeTest ft = new FinalizeTest(i);
System.out.println(ft.getId() + " 被创建了!");
}
System.gc();
}
}FinalizeTest.java
public class FinalizeTest {
private int id;
public FinalizeTest(int id) {
this.id = id;
}
public int getId() {
return id;
}
protected void finalize() throws Throwable {
System.out.println(" " + id + " 被回收了!");
}
}