在JAVA中,有垃圾回收器来进行回收不再使用的对象占据的内存,但是垃圾回收器只会释放那些由“new”关键字分配的内存,如果我们为对象分配了一个“特殊”的内存区域,则不会起到作用,为解决此问题,JAVA提供了一个名为finalize()方法,可以为我们的类定义它。但是垃圾收集并非破坏,我们的对象可能不会被当做垃圾被收掉。垃圾收集同样需要消耗一定的资源,在JVM认为没有必要去消耗额外的资源回收未占满内存的空间时,永远都不会执行垃圾回收,只有在JVM感到危机时,才会自动调用,看一段程序:
import java.util.*;
class Chair{
static boolean gcrun = false;
static boolean f = false;
static int created = 0;
static int finalized = 0;
int i;
Chair(){
i = ++created;
if(created == 47)
System.out.println("Created 47");
}
public void finalize(){
if(!gcrun){
gcrun = true;
System.out.println("Beginning to finalize after"+created+"Chairs have been created");
}
if(i == 47){
System.out.println("Finalizing Chair #47,"+"Setting flag to stop Chair creation");
f = true;
}
finalized++;
if(finalized >= created){
System.out.println("All"+finalized+"finalized");
}
}
}
public class Garbage {
public static void main(String[] args) {
// TODO Auto-generated method stub
while(!Chair.f){
new Chair();
new String("To take up space");
}
System.out.println("After all Chairs have been created:\n"+"total created="+Chair.created+",total finalized="+Chair.finalized);
if(args.length > 0){
if(args[0].equals("gc")||args[0].equals("all")){
System.out.println("gc():");
System.gc();
}
if(args[0].equals("finalize")||args[0].equals("all")){
System.out.println("runFinalization():");
System.runFinalization();
}
}
System.out.println("bye!");
}
}
程序运行结果为:
首先简单解释上述程序,该程序定义了一个Char类,并内含4个static变量,其中gcrun变量指出垃圾回收器是否开始运行;f变量使Char类告诉main()停止对象的生成;created变量用于跟踪已创建的对象数量;finalized变量用于跟踪垃圾回收器已进行完收尾工作的对象数量。当程序开始生成Char对象时,当JVM感受到空间危机时,自动调用fianlize()函数进行回收,当回收到第47个Char对象时,将f变量置为true,使得Char停止生成对象,根据运行结果来看,程序在生成520679个Char对象后开始运行垃圾回收器,同时Char仍然在不断生成对象,直到生成6992404个对象后f变量置为true停止生成,到结束时垃圾回收器一共回收了5147998个Char对象,此时JVM消除空间危机,程序停止运行。
此程序提供了命令行变量来强制进行垃圾回收机制的调用,代码为:
if(args.length > 0){
if(args[0].equals("gc")||args[0].equals("all")){
System.out.println("gc():");
System.gc();
}
if(args[0].equals("finalize")||args[0].equals("all")){
System.out.println("runFinalization():");
System.runFinalization();
}
}
同时此段为本人未看懂的地方,待将来看懂后回来修改此处,留此疑惑于此,希望有大佬能够讲解困惑,当在源程序中注解掉此段代码后的运行结果为:
最终的结果令人困惑。。。如果有人能解答此段代码的作用及原理,在此感谢