About Garbage Collector and finilize()

这是一个测试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”

估计问题就在这,版本不同结果会不同

?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值