System.gc与finalize以及Thread对象何时被回收

来源:互联网 发布:军官 知乎 编辑:程序博客网 时间:2024/05/15 07:40

System.gc()建议JVM进行一次垃圾回收。垃圾对象在被回收之前,其finalize方法会被JVM自动调用,用于做一些清除工作。简单地说,调用了System.gc()之后,java在内存回收过程中就会调用那些要被回收的对象的 finalize() 方法。

下面看一个例子。

User:

package com.zzj.gc;public class User {private String name;public User(String name) {this.name = name;}@Overrideprotected void finalize() throws Throwable {System.out.println("User " + name +" finalize");}}
MyThread:
package com.zzj.gc;public class MyThread extends Thread {private String name;public MyThread(String name) {this.name = name;}@Overridepublic void run() {try {Thread.sleep(6 * 1000);} catch (InterruptedException e) {Thread.currentThread().interrupt();e.printStackTrace();}}@Overrideprotected void finalize() throws Throwable {System.out.println(name + " finalize");}}
Test:
package com.zzj.gc;public class Test {public static void main(String[] args) throws Exception {new User("Jim");new MyThread("myThread").start();System.gc(); // Jim将被回收Thread.sleep(9 * 1000); // 等待线程myThread执行完毕System.gc(); // myThread线程对象将被回收Thread.sleep(3 * 1000);}}
输出:
User Jim finalizemyThread finalize
第一次调用System.gc()后,线程对象myThread并不会被立即回收,只有等待线程执行完毕,再次调用System.gc()后才会被回收。

当然我们也可以不调用System.gc(),而是创建大量的对象,这样垃圾回收器也会执行GC。

之所以要有finalize( ),是由于你可能在分配内存时,采用了类似C语言中的做法而非Java中的通常做法。这种情况主要发生在使用“本地方法”的情况下,它是在Java中调用非Java代码的一种方式。本地方法目前只支持C和C++。但它们可以调用其它语言写的代码,所以你实际上可以调用任何代码。在非Java代码中,也许会调用类似C的malloc( )函数,用它分配存储空间,而且除非调用了free( )函数,否则存储空间将不会得到释放,从而造成内存泄露。当然,free( )是C和C++中的函数,所以你需要在finalize( )中用本地方法调用它。




0 0