众所周知java的引用分为四种,分别是强引用,软引用,弱引用,虚引用。 今天就来说一下 他们的区别,以及作用。
内存回收
首先,如果你想看懂下面的内容,那么我强烈的推荐你先看一下我的另一篇博客java内存管理关系及内存泄露原理。如果,你已经看了上篇的文章,那么你对java内存这方面就应该有一些概念了。
现在,来说一下内存回收。可能有人会说不对啊。java里面有内存回收这东西么?不都是自动的么?由垃圾收集器(GC)来完成内存回收的工作。是的,java里面的内存回收都是由垃圾收集器操作的。但是垃圾收集器不是万能的,它只会按照自己的规则来判断 ,当前这个内存是否可以被回收,如果可以那么回收内存。
垃圾收集器判断内存是否可以回收的规则
1.内存空间当前如果没有强引用,但是有软引用,那么只有在内存耗尽的时候,才可以回收。
2.内存空间之间如果存在 环形强引用(隔离岛),没有线程可以访问到它,那么可以回收。
3. 内存空间当前如果没有强引用,没有线程可以访问到它,那么可以回收。
一共三条规则,GC是从第一条开始验证,直到最后一条。如果有一条满足,那么就是可以回收的内存。
内存空间
有人会好奇 内存空间是什么?
Island one;//声明一个Island类,此时 只是声明,没有实例
one = new Island();//开辟一个内存空间,并将内存空间和one 建立强引用
one=null;//如果,只有这三行代码,那么上面开辟出来的内存空间,将会被GC回收
内存空间 就是 new Island() 在内存中开辟出来的 一小块地方。当我们one=null的时候,刚刚开辟的内存空间,已经没有任何一个引用了,那么GC就会回收这部分内存。
有的人会比较疑问 环形强引用(隔离岛) 是什么?
public class Island {
Island i;//强引用其他对象
public static void main(String[] args) {
Island i2 = new Island();
Island i3 = new Island();
Island i4 = new Island();
i2.i = i3;//i2引用i3
i3.i = i4;//i3引用i4
i4.i = i2;//i4引用i2
i2 = null;//将对象和内存空间 断开引用
i3 = null;//将对象和内存空间 断开引用
i4 = null;//将对象和内存空间 断开引用
//这时候 就是隔离岛
// 尽管 i2,i3,i4都被强引用了,但是线程已经无法访问到他们了
// i2 i3 i4 都可以被回收
}
}
看上面这段代码,就可以看出来,Island类内部会持有自己同类型的其他类实例。上面的 i2,i3,i4都被强引用了,但是线程已经无法访问到他们了。他们之间就像是一个环,一个独立的岛。
好了,接下来 ,就可以看引用关系了。当然不是 先看一个类
Reference
这是 软引用,弱引用和虚引用的父类,大家主要关注这几个方面就行,源代