四种引用类型

四种引用类型

强引用:

强引用又称‘普通引用’,如:T t = new T();

这种引用类型永远都不会被回收。

软引用:

SoftReference<T>  m = new SoftReference<>(new T());

此种引用只有在内存不足的情况下回收,一般用于缓存对象、图片等对象,用完一次就不用的场景。

弱引用:

WeakReference<T>  m = new WeakReference<>(new T());

弱引用在调用 System.gc();时就会回收。

一般用在容器里,如ThreadLocal:

ThreadLocal 往里set值的时候,是往当前线程的Map 中放数据,key就是ThreadLocal对象,value是具体对象,在往map中set(确实是set)的时候,其实是一个Entry对象,这个Entry对象就继承了WeakReference类,是一个弱引用,当当前线程结束的时候,此时的key也就是ThreadLocal对象就会自动被回收。

 

如果这个key不是弱引用,而是强引用,在当前线程结束的时候,这个key,也就是ThreadLocal对象是不会被回收的。会导致内存泄露。

 

 

所以,使用ThreadLocal,不用以后,必须把对象remove掉。

 

WeakHashMap???

虚引用:

虚引用主要用于堆外内存的。

PhantomReference<T> m = new PhantomReference<>(new T(),QUEUE);

这个东西是给写虚拟机(JVM)的人用的,程序员一般用不上。

垃圾回收只要看到有虚引用,二话不说,直接回收。当对象被回收的时候,会通知你,将对象的引用放入QUEUE 中,也就是说,只要队列中有引用,说明这个对象已被回收。

还有一点,虚引用里边的值是get不到的。

NIO中有个DirectByteBuffer就是堆外内存(直接内存),使用的虚引用,它不归JVM管理,而是操作系统,什么时候去回收这块堆外内存呢?可以去监听这个队列,当这个队列中有值时,就去清理堆外内存。

怎么回收堆外内存?

通过Unsafe,还有直接分配内存、释放内存的api

 

 

 

内存泄露和内存溢出的区别:

内存泄露可以理解为 漏掉了一块,永远不会被回收;内存溢出是指占用的内存越来越多,占不下了导致溢出。

 

猜你喜欢

转载自blog.csdn.net/rlk512974883/article/details/106658631