java 强引用,软引用,弱引用,虚引用

强引用:

就是普遍使用的引用,如果一个对象存在一个强引用 ,java的gc是不会对它进行内存回收,如果对象过多,只有抛出异常。

软引用:(可以做缓存)

SoftReference 本身就是一个对象,它不像强引用对象,如果对象除了软引用是可达(弱引用和虚引用可以有的),没有其他的可达的化(强引用),并且内存空间不足的时候,gc会把这个对象清理掉,清理调之后,SoftReference 所指向的值将变成null。(注意:SoftReference本身也是一个引用,这个引用很软)。软引用常常用来实现高速缓存。

弱引用:(可以做缓存,这个缓存,生命周期更短)

WeakReference本身就是一个对象,它跟SoftReference对象相似,引用比它更软。当gc运行时,对象除了弱引用可达该对象(虚引用也可以有)而没有其它引用(可达),gc会对该值进行清理。因为gc第一次调用的时间不确定性,所以,对象清理放生在任何时候,在获取值前,需要判断对象是否清除掉,jdk中WeakHashMap使用了WeakReference。

虚引用:(配合使用引用队列来实现对象是否要被回收的监控)

PhantomReference本身是一个对象,这个对象跟WeakReference对象相似,引用更弱。它不能决定引用对象的生命周期,常用来判断一个对象是否要被清理掉,它get方法重写了,始终返回null。gc运行时对象只有虚引用,gc会对该值清理,因为对象可以重载finalize方法使对象复活。而且,如果重载finalize方法,不管有没有使对象复活,gc第二次才会标记清除该对象。

 

 

我在理解的时候总是觉得虚引用和弱引用是一样,最后实验中终于理解了。

首先需要理解为什么需要使用弱引用,不懂缓存机制的可以查看https://www.cnblogs.com/yw-ah/p/5830458.html

弱引用和虚引用:

相同点:它们都不会延长对象的生命周期,gc总会当他们不存在一样,只是当对象清除了会把该引用设置为null。

不同:

1、弱引用因为get()方法可以返回强引用对象,也就可以使没有被垃圾回收期回收的对象复活,重新使用,提升了性能。虚引用get()返回值总是null,意味着不能使对象复活。

2、它们还有不同在于对象finalize方法被重载的时候,如果将要清除的对象重载finalize方法,弱引用第一次就会清理,虚引用表现是第二次才会一样的(这个不需要过多理解,详细要查看jvm源码,我也不知道原因)。

当finalize重载了,不管有没有使对象复活,虚引用第二次执行gc才会把ref放入refQueue对象里面。

这儿引用一下,不要使用finalize方法,原因是https://blog.csdn.net/aitangyong/article/details/39450341

当然,虚引用我们可以替换finalize方法,当虚引用再引用队列中时,我们就执行需要再finalize里面执行的方法了。

 

你可能感兴趣的:(Java)