一、强引用
我们正常手动new出来的对象都是强应用,不对他进行别的操作的时候它是不会进行垃圾回收的。除非将它的引用断开,此时调用垃圾回收器才会将它回收。
二、软引用
三、虚引用
虚引用的意思就是,引用关系是虚的,如果创造出来,就连获取对象都获取不到,只有空间不足垃圾回收的时候,会放到一个引用队列里进行通知垃圾回收器特殊处理。
既然用都用不到这个在实际中有啥用呢?
有一个是从网线上传来一个对象数据,然后网线传送到网卡,网卡到内存中,内存到jvm中的堆空间里,其中内存到JVM是纯纯复制的一个过程,所以后把jvm里的buffer换成directBuffer直接内存,直接使用这个对象的时候直接从内存中获取提高效率,但是这块内存是不归jvm管,不归jvm管就没办法直接使用垃圾回收器处理,那么正好可以用虚引用,垃圾回收器将directBuffer垃圾回收的时候加入到弱引用队列进行统一的特殊处理。
四、弱引用
这个弱引用是可以拿到对象的,特点就是只要是垃圾回收器看到弱引用就直接无视,将对应的对象当成垃圾。面试最常考的地方是下面这个threadlocal中的弱引用部分。
ThreadLocal实际上是一个对外暴露的操作当前线程Thread中ThreadLocalMap的一个工具类,ThreadLocalMap里可以存储Entry,Entry里的key对应着当前线程实例对象,value对应着我们设置的值。其中ThreadLocalMap存储在当前Thread线程类中,所以每个线程中使用ThreadLocal获取的数据也是不同的,隔离性也是再此产生的。
就一句话的事,一个线程对应的一个ThreadLocalMap,根据线程的名字就可以获取到属于自己线程的ThreadLocalMap,一个ThreadLocalMap可以存多个值,每个值都是一个entry对象,key是对应创建的ThreadLocal对象,value随便,如果在一个线程想设置多个ThreadLocalMap的entry,就创建多个threadlocal对象就行了,这个ThreadLocalMap存在thread类里
特点:这个entry中的key此处继承了一个弱引用,它将自己的key设置成super(key),把自己的key设置成弱引用。
先看图,看图说话,先创建属性tl1指向Threadlocal对象,通过Threadlocal 这个对象引用tl1进行put操作的时候,实际上是向entry里的key存进去的是当前这个这个Threadlocal对象引用作为key。很明显我看图就知道,然后根据自己的线程获取到属于自己的ThreadLocalMap,创建对应的ThreadLocalMap空间,ThreadLocalMap里面我们学过里面存的是entry的这种key-value键值对的建构,然后这个entry其实还继承了一个弱引的类,然后会发现key都实现了父类方法,将引用类型设置成弱引用类型。然后通过栈中的成员属性指tl1指向自己创建的Threadlocal对象,这是强引用。
当我们找对应的Threadlocal,将这个Threadlocal的引用穿进去就可以找到了,因为弱引用是可以获取到对象的。不过为什么这里要用弱引用呢?
是因为如果Threadlocal这个引用属性想要断开Threadlocal对象的关系,目的是为了让threadlThreadlocalocal对象回收,因为此时不需要用Threadlocal了,此时entry里的key使用的是弱引用,也就是说连接对象的强引用断开了,就剩自己一个弱引用了,那么通过弱引用的特性,垃圾回收器只要看到弱引用就会无视它的引用,执行垃圾回收器的回收,此时就会将这个对象删除。