对象与垃圾回收

JVM

注意

  • Java的垃圾回收机制,只会负责回收堆上的对象,不会回收任何物理资源(例如数据库连接,网络IO等资源)
  • Java程序无法精确的控制垃圾回收机制的运行,垃圾回收会在合适的时候进行。
  • 在回收对象之前,会调用对象的finalize方法,该方法可能使对象复活。

对象的状态

建议结合:java虚拟机的垃圾回收器怎么判断对象“已死”进行学习。

采用可达性分析算法,对象的三种状态:

  • 可达状态 存在着到GC Root的引用链
  • 可恢复状态 不存在到达GC Root的引用链,但是finalize方法还未触发,还有可能变成可达状态
  • 不可达状态 不存在到GC Root的引用链,同时finalize方法已经执行过了

强制垃圾回收

当一个对象失去引用之后何时被回收,对于程序而言是完全透明的。程序只能控制一个对象何时不再被任何引用变量所引用,绝对不能控制他何时被回收。

程序无法精确的控制垃圾回收的时机,但是依然可以强制系统进行垃圾回收,这种强制只是通知系统进行垃圾回收,但是系统是否进行垃圾回收并不确定,大部分时候,强制系统进行垃圾回收总会收到一些效果。强制系统进行垃圾回收有如下两种方式:

  • System.gc()
  • Runtime.getRuntime.gc()

注意,这种强制只是建议系统立即进行垃圾回收,系统完全有可能并不会立即进行垃圾回收,垃圾回收机制也不会对程序的建议完全置之不理,而是会在收到通知后,尽快的进行垃圾回收。

finalize方法

建议结合:对象回收前的两次标记进行学习。

在垃圾回收机制回收对象占用的内存之前,通常要求程序调用适当的方法来清理资源,在没有明确指定清理资源的情况下,Java提供了默认的机制来清理对象的资源,这个机制就是finalize方法。这个方法是定义在Object里面的实例方法:

1
protected void finalize() throws Throwable

任何类都可以重写finalize方法,在这个方法中清理对象占用的资源,但是如果程序终止之前没有进行垃圾回收,则finalize方法不会被执行。只有当程序认为需要更多的额外内存的时候,才会进行垃圾回收。当某个失去引用的对象占用了少量内存,而且系统并没有出现内存不足的情况,这个时候不会进行垃圾回收,因此finalize方法可能完全不会被调用。

finalize方法就有如下四个特点:

  • 永远不要主动调用finalize方法,这个方法交给垃圾回收机制调用
  • 这个方法是否被调用,何时被调用具有不确定性,不要把这个方法当成一定会执行的方法
  • 当JVM执行可恢复对像的finalize方法的时候,可能使当前对象或者是系统的其他对象重新变成可达的状态
  • 当JVM执行finalize方法的时候出现异常,垃圾回收机制不会报告异常,程序继续执行。

注意,因为finalize方法可能不会被执行,所以如果想要清理某个类里面打开的资源,则不要放在finalize方法里面进行清理,而是通过try-finally进行资源的关闭清理操作。

对象的四种引用

建议阅读:四种引用

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器