finalize是JVM垃圾回收时调用的,基本上垃圾回收的时间是无法保障的,只要JVM发现一个对象无任何引用了,就会去回收它。
system.gc()只是说明代码建议JVM进行垃圾回收。
system.gc()只是说明代码建议JVM进行垃圾回收。
解决方案 »
- 设计模式是好的,但是为设计模式而设计模式就有点买椟还珠的味道了
- 怎么格式化数字成字符串,不足长度被0
- 富有挑战性的题目:CVSLIENT 关于 中文文件下载后乱麻问题(800分赠送)
- 处理Set里的值
- 要创建文件夹sp_configure要怎么设置xp打开哪个选项
- java报错,并在桌面生成一个hs_err_pid3900.log文件,请各位帮忙分析一下,谢谢!
- 请高人指点代码~~~~~~~
- 求一个比较完整的基于TCP/IP的网络收与发程序!越简单越好,多些各位了!
- java 2个程序间如何调用
- vj中如何连接sqlserver???(直连接不是jdbc-odbc)
- 郁闷!郁闷!郁闷!把分全散了!
- 链接SQLSERVER7.0为什么取不到表?
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的对象,然而
大家心里都要清楚,它其实是一个对象的引用而已。
*/
第一个程序在我机器上的执行结果是:
Begin...Hello!
Begin...
Closing...
Begin...
Begin...Hello! again.
Closing...第二个程序的执行结果是:
Begin...Hello!
Begin...
Begin...
Closing...
Closing...
Begin...Hello! again.你编译的时候没遇到错???复制你的代码到我的机器发现有编译错误,
代码没问题,但在最后一个System.gc();后,有两个非法非可显示字符,用HEX查看,
是A1 A1,删除后,编译成功.执行结果如上.楼主你试试将你现在编译出来的.class删除掉,重新编译运行试试.
我怀疑你现在用JVM运行的类是你早先编写并编译成功的字节码中的类.