大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 垃圾回收

在C++中,使用new配置的对象,必须使用delete来 清除对象,以释放对象所占据的内存空间,如果没有进行这个动作,则若对象不断的产生,内存就会不断的被耗用,最后使得内存空间用尽,然而使用 delete并不是那么的简单,如果不小心清除了尚被引用的对象,或是对象间共用的资源,则程序就会发生错误,小心的使用new与delete,一直是C ++中一个重要的课题。

在Java中,使用new配置的对象,基本上也是必须清除以回收内存空间的,但是您并不用特别关心这个问题,因为Java提供“垃圾收集”(Garbage collection)机制,在适当的时候,Java执行环境会自动检查对象,看看是否有未被引用的对象,如果有的话就清除对象、回收对象所占据的内存空间。

垃圾收集的时机我们并无法得知,可能是内存资源不足的时候,或是在程序空闲的时候,您可以建议执行环境进行垃圾收集,但也仅止于建议,如果程序当时有优先权更高的线程(Thread)正在进行,则垃圾收集并不一定会马上进行。

在C++中有解构方法(Destructor),它会在对象被清除前执行,在Java中并不明确有解构方法,因为我们不知道对象什么时候会被回收,在Java中有finalize()这 个方法,它被声明为protected,它会在对象被回收时执行,但您不可以将它当作解构方法来使用,因为不知道对象资源何时被回收,所以也就不会立即执 行我们所指定的动作,但您可以使用finalize()来进行一些相关资源的清除动作,而这些动作与立即性的收尾动作并没有关系。

如果我们确定某个对象不再使用,您可以在指向该对象的名称上指定null,表示这个名称不在指向任何对象,可以使用System.gc()建议程序进行垃圾收集,如果建议被采纳,则对象资源会被回收,回收前会执行finalize()方法。

下面这个程序是个简单的示范:


  • GcTest.java
public class GcTest { 
private String name;

public GcTest(String name) {
this.name = name;
System.out.println(name + "建立");
}

// 对象回收前执行
protected void finalize() {
System.out.println(name + "被回收");
}
}

  • UseGC.java
public class UseGC { 
public static void main(String[] args) {
System.out.println("请按Ctrl + C终止........");

GcTest obj1 = new GcTest("object1");
GcTest obj2 = new GcTest("object2");
GcTest obj3 = new GcTest("object3");

// 令名称不指向对象
obj1 = null;
obj2 = null;
obj3 = null;

// 建议回收对象
System.gc();

while(true); // 不断执行program
}
}

执行结果:
请按Ctrl + C终止........
object1建立
object2建立
object3建立
object1被回收
object2被回收
object3被回收 


您故意加上无穷循环,以让垃圾收集在程序结束前有机会执行,藉以了解垃圾收集确实会运作。