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;
}
@Override
protected 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;
}
@Override
public void run() {
try {
Thread.sleep(6 * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
@Override
protected 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 finalize
myThread finalize
第一次调用System.gc()后,线程对象myThread并不会被立即回收,只有等待线程执行完毕,再次调用System.gc()后才会被回收。
当然我们也可以不调用System.gc(),而是创建大量的对象,这样垃圾回收器也会执行GC。
之所以要有finalize( ),是由于你可能在分配内存时,采用了类似C语言中的做法而非Java中的通常做法。这种情况主要发生在使用“本地方法”的情况下,它是在Java中调用非Java代码的一种方式。本地方法目前只支持C和C++。但它们可以调用其它语言写的代码,所以你实际上可以调用任何代码。在非Java代码中,也许会调用类似C的malloc( )函数,用它分配存储空间,而且除非调用了free( )函数,否则存储空间将不会得到释放,从而造成内存泄露。当然,free( )是C和C++中的函数,所以你需要在finalize( )中用本地方法调用它。