Java的内存回收机制

来源:互联网 发布:通联数据网站 编辑:程序博客网 时间:2024/06/05 15:42

JVM的垃圾回收采用有向图方式来管理内存中对象,因此可以很方便地解决循环引用的问题,只要从有向图的起始顶点不可到达它们,垃圾回收机制就会回收它们。采用有向图来管理内存具有较高的精度,但缺点是效率较低。

当一个对象在堆内存中运行时,根据有向图中的状态,分为三种情况:

1、可达状态:对象被创建,有一个以上的引用变量引用它,在有向图中可从起始顶点导航到该对象,它就处于可达状态。

2、可恢复状态:程序中某个对象不再有任何引用变量引用它,它将进入可恢复状态,此时从有向图的顶点不能导航到该对象,此时系统会调用可恢复状态的对象finalize方法进行资源清理,如果系统在调用finalize方法重新让一个以上引用变量引用该对象,则这个对象会再次变为可达状态,否则该对象将进入不可达状态。

3、不可达状态:当对象的所有关联都被切断,且系统调用所有对象的finalize方法依然没有使该对象恢复可达状态,则这个对象永久性失去引用,变为不可达。


Java在java.lang.ref包下提供了3个类:SoftReference/PhantomReference/WeakReference,分别代表系统对象三种引用方式:软引用、虚引用、弱引用

java的引用主要如下:

1、强引用

2、软引用

3、虚引用

4、弱引用


1、强引用:

java程序中最常见的引用方式,程序创建一个对象,并把这个对象赋给一个引用变量,这个引用变量就是强引用。

由于JVM肯定不会回收强引用java对象,则强引用是造成java内存泄漏的主要原因。


2、软引用:

软引用需要通过SoftReference类来实现,对于只有软引用的对象而言,当系统内存空间足够时,它不会被系统回收,程序也可使用该对象,当系统内存不足时,系统将会回收它。可以看出来当系统内存足够时,软引用和强引用没有什么区别。所以软引用是强引用很大的替代。

可以调用System.gc()与System.runFinalization()来通知系统进行垃圾回收。


3、弱引用:

弱引用所引用的对象的生存期更短,弱引用通过WeakReference类实现,弱引用虽然和软引用很想,但是弱引用的引用级别更低,对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管内存是否足够,总会回收该对象所占用的内存。并不是说有一个弱引用就会回收,而是等到系统垃圾回收机制运行时才会被回收。

弱引用具有很大的不确定性,因为垃圾回收机制不受程序员的控制,因此程序获取弱引用的Java对象时必须小心空指针异常。

与WeakReference功能类似的还有WeakHashMap,当程序有大量的Java对象需要使用弱引用,可以考虑使用WeakHashMap来保存它们。


4、虚引用:

软引用和弱引用可以单独使用,但虚引用不能单独使用,单独使用虚引用没有太大的意义。虚引用的主要作用就是跟踪对象被垃圾回收的状态,程序通过检查与虚引用关联的引用队列中是否已经包含指定的虚引用,从而了解虚引用所引用的对象是否即将被回收。

引用队列为java.lang.ref.ReferenceQueue类表示。它用于保存被回收后对象的引用。

虚引用通过PhantomReference类实现,它完全类似于没有引用,它只用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,必须和引用队列联合使用。

使用这些引用类可以避免在程序执行期间将对象留在内存,如果以软引用、弱引用和虚引用的方式引用对象,垃圾回收器就能够随意地释放对象。

0 0
原创粉丝点击