这是一个测试finilize()的程序:
class fin {
String s = "Begin...";
fin() {
System.out.println(this.s);}
fin(String s) {
System.out.println(this.s + s);}
public void finalize() {
System.out.println("Closing...");}
}
public class t4eleven {
public static void main (String args[]) {
?fin a = new fin("Hello!");
?new fin();
?System.gc();
?new fin();
?fin b = new fin("Hello! again.");
?System.gc();
}
}
得结果:
Begin...Hello!
Begin...
Begin...
Begin...Hello! again.
Closing...
Closing...
但如果程序改为:
class fin {
String s = "Begin...";
fin() {
System.out.println(this.s); }
fin(String s) {
System.out.println(this.s + s); }
public void finalize() {
System.out.println("Closing..."); }
}
public class t4eleven {
public static void main (String args[]) {
fin a = new fin("Hello!");
?new fin();
?new fin();
?System.gc();
fin b = new fin("Hello! again.");
?System.gc();
}
}
结果会变成:
Begin...Hello!
Begin...
Begin...
Closing...
Begin...Hello! again.
Closing...
=============
finalize是JVM垃圾回收时调用的,基本上垃圾回收的时间是无法保障的,只要JVM发现一个对象无任何引用了,就会去回收它。
system.gc()只是说明代码建议JVM进行垃圾回收。
===============
/*
Well,垃圾回收是这样的,它的原理是一种编译器技术,
称之为“引用计数”技术,也就是说,每个创建的对象,在
虚拟机的某个地方,保存着对象被引用的数目,如果没有
引用指向某个对象,那么那个对象就是垃圾。
然而JVM不会马上就把那个垃圾回收掉,而要等到JVM发现
内存不足时,它才会将所有的垃圾回收,这样其实更好,
频繁的回收垃圾反而会使系统的效率降低。当然你也可以
显示的调用垃圾回收来回收垃圾(System.gc())。
第一个程序的执行结果
也是错的,应该是:
Begin...Hello!
Begin...
Closing...
Begin...
Begin...Hello! again.
Closing...
为了更好的理解垃圾回收,下面附上一个清晰的例子:
主体还是沿用原代码,不过在fin类中加一个私有的
整型数据id作为对象的标识,再定义一个静态的整型变量
count,来统计fin生成的对象数。构造函数只取无参的,
以下是完整的代码:
*/
//t4eleven.java
class fin
{
int id=0;//记录对象的标识号
static int count=0;//计数生成的对象数
fin()
{
count++;
setID(count);
System.out.println("fin类对象 "+id+" 被构造");
}
private void setID(int id)//设置对象的标识号
{
this.id=id;
}
?
public void finalize()
{
System.out.println("fin类对象 "+id+" 被回收");
}
}
public class t4eleven
{
public static void main (String args[])
{
fin a = new fin();//对象1被构造,并且被a引用
new fin();//对象2被构造,但是个匿名对象,只能引用一次,用完就是垃圾
System.gc();
//对象2被回收,而对象1则因为有a引用,不看作是垃圾,不回收
new fin();//对象3被构造,用完一次就没有指向它的引用了,因而就是垃圾
new fin();//对象4被构造,(同上)
fin b=new fin();//对象5被构造
System.gc();
//对象3和4被回收,而对象5则因为有b引用,不看作是垃圾,不回收??
}
}
/*执行结果:
---------
fin类对象 1 被构造
fin类对象 2 被构造
fin类对象 2 被回收
fin类对象 3 被构造
fin类对象 4 被构造
fin类对象 5 被构造
fin类对象 3 被回收
fin类对象 4 被回收
---------
*/
/*
当new fin()产生一个对象时,
它都是一个匿名的对象(编译器内部会给它一个名称)
而fin a=new fin();做的事情是,先构造一个对象(其实
也可以理解为是匿名的,然后返回它的地址给a,也就说
a引用了那个匿名对象),所以严格的讲,a其实并不是对象
它只是一个对象的引用,只是在JAVA中,为了便于交流
和理解,一致达成共识,将a看作为是一个fin的对象,然而
大家心里都要清楚,它其实是一个对象的引用而已。
*/
==============
“那是否是说情况会由于jvm的不同,在处理的机制上也存在差异,而导致输出结果的次序不同呢?”
对
“在System.gc()出现的地方不是应该强制执行garbage collection的吗?”
不是强制,只是建议JVM进行垃圾收集,JVM完全有权忽略这个建议
“其实我用的是jdk1.2.1”
估计问题就在这,版本不同结果会不同
?