强引用
平常我们使用的引用均为强引用,即new一个对象,通过等号赋值运算符赋值给一个变量,那么这个变量就强引用于新创建的那个对象。
只要沿着GC Root对象的引用链能找到这个对象,这个对象就不会被回收
软引用
只要某个对象没有被强引用直接引用,当垃圾回收时,即使垃圾回收结束了,仍然内存不足,就会将软引用的对象,进行回收。
FullGC结束后
弱引用
只要发生了垃圾回收,不管是否内存充足,都会被垃圾回收,即仅仅能存活到下次垃圾回收之前
软引用和弱引用还可以配合引用队列工作,如果被软引用引用的对象,被分配到了一个引用队列,那他所引用的对象被回收时,会进入引用队列,弱引用同理
不管是软引用也好,弱引用也好,它们本身一定占据着一定的内存,内存也需要被释放掉。
虚引用
必须配合引用队,被referenceHandler线程监控,调用对象中的方法,执行相关操作。
例如直接内存中的虚引用Cleaner也指向bytebuffer,bytebuffer(直接内存)会传入一个直接内存的地址到Cleaner中,
一旦byteBuffer没有强引用所引用,就会被垃圾回收掉,但是byteBuffer所申请的直接内存不受java管理,所以我们就得byteBuffer被回收的时候,虚引用对象(Cleaner)就会进入引用队列,referenceHandler会找有没有新入队的cleaner,调用Cleaner的clean方法,调用unsafe.freeMemory,释放掉直接内存。
终结器引用
对象都有一个finallize()方法,会在对象被垃圾回收的时候被调用,当没有强引用引用这个对象时候,且这个对象重写了终结器方法,虚拟机会帮助我们为这个对象创建一个终结器引用,被回收之前会放入引用队列,finallizeHandler线程会查看这个队列中是否有终结器引用,会根据这个引用,找到这个对象,调用这个对象的finallize方法,(此时对象可能自救),不推荐使用这个方法。