Java中的强引用、弱引用、软引用、虚引用

1.强引用

Object obj = new Obje()

只要强引用存在,垃圾回收器就不会回收被引用的对象,当JVM内存空间不足,JVM宁愿抛出OutOFMemoryError运行时错误,使程序异常终止,也不会靠随意回收具有强引用的“存活“的对象来解决内存不足的问题。


2.弱引用

3.软引用

这写有用但是并非必须的对象,在系统将要发生内存溢出之前,会把这项对象列进回收范围进行二次回收,如果这次回收还是没有足够的内存将会抛出内存溢出异常

弱引用是使用WeakReference包装的,他的生命周期比软引用短。因为不管当前内存空间足够与否,都会回收它的内存。由于垃圾回收器是一个优先级犯低的线程,因此不一定会很怏回收弱引用的对象。

假没我们现在我们维护一个图书的hashMap,每本书都对应一对键值对, key是图书, value是图书编码,如果某本书不存在了,我们将它的Book对象的引用置为null,但这个Book对象并不会被回收,因为它被这个Map 引用。如果恝要这个book对象被回收,还要将这键值对从这个map移除才行。


这个工作我们可以让垃圾收集器来完成,使用一个指向Book的弱引用对象来作为key就可以完成这个工作:
只需这样定义这弱引用对象:

Book bookA = new Book( );
weakReference weakBookA = new weakReference<>(bookA);


Java提供了 WeakHashMap类,使用这个map,它的key自然就是弱引用对象,无需手动包装原始对象。这样当bookA变为null时(表明它所引用的Book已经无需存在于内存中),这时指向这个Book对象的就是由弱引用对象weakBookA 了,那么显然这时候相应的Book对象是弱可达的,所.指向它的弱引用会被清除,这个Book对象随即会被回收,指向它的弱引用对象会进入引用队列中。


4.虚引用

虚引用是使用PhantomReference创建的引用,虚引用也称为幽录引用或者幻影引用,是所有引用类型中最弱的一个。一个对象是否有虚引用的存在,完全不会对其生命周期构成影响,也无法通过虚引用获得一对象实例。
 

string str = new string( "abc" );
ReferenceQueue queue = new ReferenceQueue( );
//创建虚引用,要求必须与一个引用队列关联
PhantomReference pr = new PhantomReference(str, queue) ;

虚引用的作用在于距踪垃圾回收过程,在对象被收集器回收时收到一个系统通知。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,将这个虚引用加入引用队列,在其关联的虚引用出队前,不会彻底销毁该对象。所以可以通过检查引用队列中是否有相应的虚引用来判断对象是否已经被回收了。


如果一个对象没有强引用和软引用,对于垃圾回收器而言便是可被清除的,在清除之前,会调用其finalize方法,如果一个对象己经被凋用过finalize方法但是还粪有被释放,它就变成了一个虚可达对象。
与软引用和弱引用不同,显式使用虚引用可以阻止对象被靖除,只有在程序中显式或者隐式移除这个虚引用时,这个己经执行过finalize方法的对象才会被清除。想要显式的移除虚引用的话,只
需要将其从引用队列中取出然后扔掉(置为null))即可。虚引用有一个很重要的用途就是用来做堆外内存的释放
DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。

5.总结
 

强引用        jvm宁愿出现oom,也不会回收的对象
弱引用 内存不足时会尝试回收
软引用 会被垃圾收集器直接回收
虚引用 可以用来判断对象是否被回收

你可能感兴趣的:(Java,java)