1.强引用
比如说new 了个对象,这个对象赋值给一个变量。这个变量就强引用这个对象。强引用的特点就是沿着GC root引用链能够找到它,那它就不会被垃圾回收掉。
2.软引用
当一个对象没有被强引用时,而是被软引用对象所引用。软引用的特点就是当发生垃圾回收时内存仍然不足时,这个时候这个对象会被垃圾回收掉。这里引入一下引用队列,由于软引用对象或者弱引用对象本身也是一个对象,当想释放他们的时候,把他们加入到引用队列当中。然后在引用对垒中找到他们,然后对软引用和弱引用进行内存释放。
3.弱引用
弱引用的特点就是当发生垃圾回收时,不管内存是否足够,这个对象都会被垃圾回收掉。
4.虚引用
当创建ByteBuffer时会创建一个Cleaner虚引用对象,ByteBuffer会分配一块直接内存,这个直接内存地址传递给虚引用对象Cleaner。当没有强引用ButeBuffer对象时,会被垃圾回收掉,但是直接内存是堆外内存,并不会被垃圾回收掉,此时,Cleaner虚引用对象会被放入到引用队列当中。这个引用队列有个ReferenceHandler线程来定时地寻找新入队的Cleaner线程,如果有就会调用Cleaner中的clean方法,这里面有个Unsave的unsave.freeMemory内存释放掉,这个直接内存就被释放了。
5.终结器引用
我们都知道所有的java对象都会继承Object类,Object类中有finalize()方法,当这个对象重写了这个方法并且没有强引用引用它时,就会被垃圾回收了。那finalize方法什么时候被调用呢?当该对象没有被强引用引用时,虚拟机会创建终结器引用,当这个对象被垃圾回收时,终结器引用对象被加入到引用队列当中,这个时候对象并没有被回收,等到引用队列有个优先级比较低的finalizeHandler线程在某个时间找到新加入的终结器引用对象,这个时候进行垃圾回收该对象。但终结器引用一般不用,我刚刚说了优先级比较低,很可能该对象迟迟得不到释放。