浅谈垃圾回收机制
2013-07-09 16:11
357 查看
1、 何时对象被抛弃
一个对象,可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时,这个对象就被应用抛弃了。或者说,这个对象可以被垃圾回收机制回收了。
JVM的垃圾回收机制对堆空间做实时监测,当发现某对象的引用计数为0时,就将该对象列入待回收列表中,并不是马上予以销毁。
2、 是否丢弃即被回收
并不是对象被抛弃后就立即被回收。JVM进程做空间回收有较大的系统开销,如果每当应用进程丢弃一个对象,就立即回收空间,势必将会降低整个系统的运转效率。
JVM的垃圾回收机制有多个算法。除了引用计数法是用来判断对象是否已被抛弃外,其他算法是用来确定何时及如何做回收。JVM垃圾回收机制要在时间和空间之间做个平衡。
因此,用户无法知道垃圾回收发生的精确时间。
3、 干预系统回收
对垃圾回收机制来说,只有两个途径发消息给JVM。第一个途径是将指向某对象的所有引用全部移走,相当于向JVM发了一个消息:这个对象不要了。第二个途径是调用库方法System.gc()。
调用System.gc()也仅仅是一个回收请求。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做加权,使垃圾回收操作容易发生,或提早发生。
Java的垃圾回收机制是为所有Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么,怎么做或做多少。
4、 finalize()方法
一个对象在运行时,可能会有一些东西与其关联。因此,当对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法(常称之为终止器)里,如下所示:
Protected void finalize(){//finalization codehere}
这个终止器类似于C++里的析构函数,都是自动调用的,但是两者的调用时机不一样,使两者的表现行为有重大区别。
C++的析构函数总是当对象离开作用域时被调用。这就是说,C++析构函数的调用时机是确定的,且可以在编码中把握。Java终止器在对象被销毁时调用,被丢弃的对象何时被销毁不得而知,而且,对于大多数场合,被丢弃对象在应用终止后仍未销毁。
在编码时,应该考虑到这一点。例如,某对象在运行时打开了某个文件,该对象被丢弃时没有关闭这个文件,而是把文件关闭语句写在终止器里。如果文件是独占打开的,则其他对象将无法访问这个文件。如果文件是共享打开的,则另一访问该文件的对象直至程序终结仍不能读到被丢弃对象写入该文件的新内容。
当应用终止,会不会执行应用中的所有finalize()呢?据Bruce Eckel在《Thinking in java》里的观点:“到程序结束的时候,并非所有收尾,模块都会得到调用。”这还仅仅是指应用正常终止的场合,非正常终止呢?因此,哪些收尾操作可以放在finalize()里,是需要斟酌的。
一个对象,可以有一个或多个引用变量指向它。当一个对象不再有任何一个引用变量指向它时,这个对象就被应用抛弃了。或者说,这个对象可以被垃圾回收机制回收了。
JVM的垃圾回收机制对堆空间做实时监测,当发现某对象的引用计数为0时,就将该对象列入待回收列表中,并不是马上予以销毁。
2、 是否丢弃即被回收
并不是对象被抛弃后就立即被回收。JVM进程做空间回收有较大的系统开销,如果每当应用进程丢弃一个对象,就立即回收空间,势必将会降低整个系统的运转效率。
JVM的垃圾回收机制有多个算法。除了引用计数法是用来判断对象是否已被抛弃外,其他算法是用来确定何时及如何做回收。JVM垃圾回收机制要在时间和空间之间做个平衡。
因此,用户无法知道垃圾回收发生的精确时间。
3、 干预系统回收
对垃圾回收机制来说,只有两个途径发消息给JVM。第一个途径是将指向某对象的所有引用全部移走,相当于向JVM发了一个消息:这个对象不要了。第二个途径是调用库方法System.gc()。
调用System.gc()也仅仅是一个回收请求。JVM接受这个消息后,并不是立即做垃圾回收,而只是对几个垃圾回收算法做加权,使垃圾回收操作容易发生,或提早发生。
Java的垃圾回收机制是为所有Java应用进程服务的,而不是为某个特定的进程服务的。因此,任何一个进程都不能命令垃圾回收机制做什么,怎么做或做多少。
4、 finalize()方法
一个对象在运行时,可能会有一些东西与其关联。因此,当对象即将被销毁时,有时需要做一些善后工作。可以把这些操作写在finalize()方法(常称之为终止器)里,如下所示:
Protected void finalize(){//finalization codehere}
这个终止器类似于C++里的析构函数,都是自动调用的,但是两者的调用时机不一样,使两者的表现行为有重大区别。
C++的析构函数总是当对象离开作用域时被调用。这就是说,C++析构函数的调用时机是确定的,且可以在编码中把握。Java终止器在对象被销毁时调用,被丢弃的对象何时被销毁不得而知,而且,对于大多数场合,被丢弃对象在应用终止后仍未销毁。
在编码时,应该考虑到这一点。例如,某对象在运行时打开了某个文件,该对象被丢弃时没有关闭这个文件,而是把文件关闭语句写在终止器里。如果文件是独占打开的,则其他对象将无法访问这个文件。如果文件是共享打开的,则另一访问该文件的对象直至程序终结仍不能读到被丢弃对象写入该文件的新内容。
当应用终止,会不会执行应用中的所有finalize()呢?据Bruce Eckel在《Thinking in java》里的观点:“到程序结束的时候,并非所有收尾,模块都会得到调用。”这还仅仅是指应用正常终止的场合,非正常终止呢?因此,哪些收尾操作可以放在finalize()里,是需要斟酌的。
相关文章推荐
- 浅谈js中的垃圾两种回收机制
- 浅谈V8引擎中的垃圾回收机制
- 浅谈关于C#的垃圾回收机制
- 浅谈Python的垃圾回收机制
- 浅谈Flash的垃圾回收机制
- 浅谈Chrome V8引擎中的垃圾回收机制
- 浅谈JAVA垃圾回收机制
- 浅谈Flash的垃圾回收机制
- 浅谈PHP垃圾回收机制
- 浅谈Flash的垃圾回收机制
- Android开发之浅谈垃圾回收机制GC以及如何用好GC
- 浅谈Python的垃圾回收机制
- 浅谈Java垃圾回收机制
- 浅谈JVM的实现与垃圾回收机制
- 浅谈java的垃圾回收机制
- 浅谈V8引擎中的垃圾回收机制
- Java 开发中之十一:浅谈java中的垃圾回收机制及变量内存分配
- 浅谈 JAVA垃圾回收机制
- 浅谈JVM的实现与垃圾回收机制
- JVM垃圾回收机制GC