网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  java的垃圾回收机制研究     
  文章作者:未知  文章来源:水木森林  
  查看:79次  录入:管理员--2007-11-17  
 

  一、谁在做garbage collection?

  一种流行的说法:在c++里,是系统在做垃圾回收;而在java里,是java自身在做。

  在c++里,释放内存是手动处理的,要用delete运算符来释放分配的内存。这是流行的说法。确切地说,是应用认为不需要某实体时,就需用delete告诉系统,可以回收这块空间了。这个要求,对编码者来说,是件很麻烦、很难做到的事。随便上哪个bbs,在c/c++版块里总是有一大堆关于内存泄漏的话题。

  java采用一种不同的,很方便的方法:garbage collection.垃圾回收机制放在jvm里。jvm完全负责垃圾回收事宜,应用只在需要时申请空间,而在抛弃对象时不必关心空间回收问题。

  二、对象在啥时被丢弃?

  在c++里,当对象离开其作用域时,该对象即被应用抛弃。

  是对象的生命期不再与其作用域有关,而仅仅与引用有关。

  java的垃圾回收机制一般包含近十种算法。对这些算法中的多数,我们不必予以关心。只有其中最简单的一个:引用计数法,与编码有关。

  一个对象,可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时,这个对象就被应用抛弃了。或者说,这个对象可以被垃圾回收机制回收了。

  这就是说,当不存在对某对象的任何引用时,就意味着,应用告诉jvm:我不要这个对象,你可以回收了。

  jvm的垃圾回收机制对堆空间做实时检测。当发现某对象的引用计数为0时,就将该对象列入待回收列表中。但是,并不是马上予以销毁。

  三、丢弃就被回收?

  该对象被认定为没有存在的必要了,那么它所占用的内存就可以被释放。被回收的内存可以用于后续的再分配。

  但是,并不是对象被抛弃后当即被回收的。jvm进程做空间回收有较大的系统开销。如果每当某应用进程丢弃一个对象,就立即回收它的空间,势必会使整个系统的运转效率非常低下。

  前面说过,jvm的垃圾回收机制有多个算法。除了引用计数法是用来判断对象是否已被抛弃外,其它算法是用来确定何时及如何做回收。jvm的垃圾回收机制要在时间和空间之间做个平衡。

  因此,为了提高系统效率,垃圾回收器通常只在满足两个条件时才运行:即有对象要回收且系统需要回收。切记垃圾回收要占用时间,因此,java运行时系统只在需要的时候才使用它。因此你无法知道垃圾回收发生的精确时间。

  四、没有引用变量指向的对象有用吗?

  前面说了,没挂上引用变量的对象是被应用丢弃的,这意味着,它在堆空间里是个垃圾,随时可能被jvm回收。

  不过,这里有个不是例外的例外。对于一次性使用的对象(有些书称之为临时对象),可以不用引用变量指向它。举个最简单也最常见的例子:

  system.out.println(“i am java!”);

  就是创建了一个字符串对象后,直接传递给println()方法。

  五、应用能干预垃圾回收吗?

  许多人对java的垃圾回收不放心,希望在应用代码里控制jvm的垃圾回收运作。这是不可能的事。对垃圾回收机制来说,应用只有两个途径发消息给jvm.第一个前面已经说了,就是将指向某对象的所有引用变量全部移走。这就相当于向jvm发了一个消息:这个对象不要了。第二个是调用库方法system.gc(),多数书里说调用它让java做垃圾回收。

  第一个是一个告知,而调用system.gc()也仅仅是一个请求。jvm接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做了加权,使垃圾回收操作容易发生,或提早发生,或回收较多而已。

  希望jvm及时回收垃圾,是一种需求。其实,还有相反的一种需要:在某段时间内最好不要回收垃圾。要求运行速度最快的实时系统,特别是嵌入式系统,往往希望如此。

  java的垃圾回收机制是为所有java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么、怎么做或做多少。

  六、对象被回收时要做的事

  一个对象在运行时,可能会有一些东西与其关连。因此,当对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法(常称之为终止器)里。

  protected void finalize()

  {

  // finalization code here

  }

  这个终止器的用途类似于c++里的析构函数,而且都是自动调用的。但是,两者的调用时机不一样,使两者的表现行为有重大区别。c++的析构函数总是当对象离开作用域时被调用。这就是说,c++析构函数的调用时机是确定的,且是可被应用判知的。但是,java终止器却是在对象被销毁时。由上所知,被丢弃的对象何时被销毁,应用是无法获知的。而且,对于大多数场合,被丢弃对象在应用终止后仍未销毁。

  在编码时,考虑到这一点。譬如,某对象在运作时打开了某个文件,在对象被丢弃时不关闭它,而是把文件关闭语句写在终止器里。这样做对文件操作会造成问题。如果文件是独占打开的,则其它对象将无法访问这个文件。如果文件是共享打开的,则另一访问该文件的对象直至应用终结仍不能读到被丢弃对象写入该文件的新内容。

  至少对于文件操作,编码者应认清java终止器与c++析构函数之间的差异。

  那么,当应用终止,会不会执行应用中的所有finalize()呢?据bruce eckel在thinking in java里的观点:“到程序结束的时候,并非所有收尾模块都会得到调用”。这还仅仅是指应用正常终止的场合,非正常终止呢?

  因此,哪些收尾操作可以放在finalize()里,是需要酌酎的。

 
 
上一篇: 事件监听器 将javabeans接通起来的方法(2)    下一篇: eclipse插件管理小结
  相关文档
利用yahoo! search api开发自已的搜索引擎-javascript版 11-16
lesson1.04配j2ee环境及cloudscape数据库 11-17
比较hashtable类和hashmap类的不同之处 11-16
基于java的web服务器工作原理(2) 11-17
ejb轻松进阶之三 11-16
敏捷开发的必要技巧:移除重复代码 11-17
使用java解析网络数据流的三种特殊方法 11-22
java打印程序设计 11-17
java程序如何穿透带有密码验证的代理 11-16
java获取本机的ip地址 11-17
书评:java的盛宴(中) 11-16
apple 更新 java 到 v1.4.1 11-17
[java100例]035、获取文件信息 11-17
ejb轻松进阶之七 11-16
懂得何时重用已有异常 11-17
ejb中数据验证出现在什么地方最合适 11-17
struts+hibernate中解决汉字编码问题 11-16
使用midp2.0开发游戏(2)使用sprite 11-17
实现java跨平台运行的十二个注意事项 11-17
精通必学:eclipse快捷键指南 11-16
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息