1、垃圾回收机制
垃圾回收机制(Garbage Collection,简称GC)只负责回收堆内存中的对象,对象在堆内存可分为可达(有一个或以上的引用)、可恢复(没有任何引用,但可以在finalize()中重新让一个引用变量引用该对象,这样该对象变为可达状态)、不可达(系统调用完finalize()后该对象仍然没有任何引用)三种状态,只有对象为不可达状态,系统才进行垃圾回收。
垃圾回收机制会在对象失去引用后在合适的时候进行内存回收。在程序中调用System.gc()或Runtime.getRuntime().gc()可以进行强制垃圾回收,但这只是通知系统进行垃圾回收,系统是否进行垃圾回收、何时进行垃圾回收都不确定。
GC对对象进行垃圾回收之前会调用对象的finalize()方法,可以重写该方法,在其中重新让一个引用变量引用该对象,这样该对象就不会被回收。finalize()由系统自动调用,何时调用以及是否调用都是不确定的,可以调用System.runFinalization()或Runtime.getRuntime().runFinalization()来强制垃圾回收机制调用对象的finalize()方法。执行finalize()出现异常时,垃圾回收机制不会报告异常,程序会继续执行。建议避免使用finalize()方法,因为定义了finalize()方法后垃圾收集的时间可能会被延迟,如果这些对象会大量产生的话,可能会因为垃圾回收被延迟而使得这些对象迟迟不能被回收,最后可能导致内存不足。
2、四种引用
强引用:普通常见的引用。
软引用:通过SoftReference类实现,当对象只有软引用的时候,可能会被垃圾回收机制回收,比如系统内存不足的时候。软引用通常用于对内存敏感的程序中。
弱引用:通过WeakReference类实现,当对象只有弱引用的时候,它总会被垃圾回收机制在合适的时候进行回收。
虚引用:通过PhantomReference类实现,虚引用完全类似于没有引用,它主要用于跟踪对象被垃圾回收的状态,必须和引用队列ReferenceQueue联合使用,当对象被垃圾回收之后虚引用将被放到引用队列中。
除了强引用外,其它引用类都有一个get()方法用来获取他们所引用的对象,下面程序展示了弱引用引用的对象被垃圾回收的过程:
import java.lang.ref.*;
public class ReferenceTest
{
public static void main(String[] args)
{
String str = new String("hello world");
WeakReference wr = new WeakReference(str); //创建弱引用
ReferenceQueue rq = new ReferenceQueue(); //创建引用队列
PhantomReference pr = new PhantomReference(str, rq); //创建虚引用
str = null; //对象只剩一个弱引用
System.out.println(wr.get()); //正常输出"hello world",垃圾回收机制没有立即回收该对象。
System.gc(); //通知系统进行垃圾回收
System.runFinalization(); //强制垃圾回收机制调用对象的finalize()方法
System.out.println(wr.get() == null); //输出为true,弱引用指向的对象被回收后调用get()获得为null
System.out.println(rq.poll() == pr); //输出为true,对象被回收之后虚引用将被放到设置的引用队列中,poll()方法取出最先进入引用队列的引用。
}
}
由于垃圾回收的不确定性,当从软引用或弱引用中取出被引用对象时,可能这个对象已经被释放了(调用引用的get()方法返回为null),如果程序需要使用那个对象,则必须重新创建该对象。
3、java中终止程序的方法:
System.exit(0);
Runtime.getRuntime().exit(0);