类在实例化的过程中,Java虚拟机会为实例化的对象分配内存,同时也为对象内的成员变量和成员方法分配存储空间。实例化的每个对象都是相互独立的,在内存中占据独立的内存地址,并且每个对象都有自己的生命周期,当一个对象的生命周期结束时,对象变成了垃圾,由Java 虚拟机自带的垃圾回收机制进行处理,该对象就不能再使用了。
Java虚拟机是如何判断对象可以被回收呢?
对象的生命周期与对象的有效范围有关。在《变量的有效范围》一课中谈到了变量分为全局变量和局部变量:类的成员变量都是全局变量;在类方法内部声明的变量是局部变量。全局变量的有效范围为整个类,局部变量的有效范围为类方法内部。
如果在类方法内部创建的实例化对象,当这个类方法执行完成后,将会被回收。因为类方法执行完成后,类方法执行时分配的栈空间(用来存储局部变量的存储空间)被清理,方法内部的实例化对象已经失去了有效范围。
例如下面的代码,当方法执行完成后,String对象s将被Java 虚拟机自动回收。
public void mthod()
{
String s = new String("这是一个方法");
System.out.println(s);
}还有一种情况就是程序员主动将已实例化的对象设置为null,在这种情况下,虽然实例化的对象可能还在有效范围之内,Java虚拟机也会自动回收这类对象。
public void mthod()
{
String s = new String("这是一个方法");
s = null;
……
}垃圾对象由Java 虚拟机自动回收。如果程序员希望在垃圾对象回收之前做一些对象的资源清理工作,可以重写Object类的finalize()方法,在finalize()方法内部做对象资源的清理工作。
@Override
protected void finalize() throws Throwable {
// 清理资源的代码
…………
super.finalize();
}
类重写Object类的finalize()方法后,Java 虚拟机会判断对象是否重写了finalize()方法,如果没有重写,则直接将其回收。否则,会在垃圾回收时调用该方法,并且在下一次进行垃圾回收时,再回收对象占有的内存资源。
由于Java虚拟机的垃圾自动回收不受人为控制,具体执行时间也不确定。为此,Java提供了System.gc()方法来强制启动垃圾回收器,让Java虚拟机进行对象的回收工作。