强引用(StrongReference)
强引用就是指在程序代码之中普遍存在的, 比如下面这段代码中的 object 和 str 都是强引用:
- Object object = new Object();
- String str = "hello";
只要某个对象有强引用与之关联, JVM 必定不会回收这个对象, 即使在内存不足的情况下, JVM 宁愿抛出 OutOfMemory 错误也不会回收这种对象比如下面这段代码:
- public class Main {
- public static void main(String[] args) {
- new Main().fun1();
- }
- public void fun1() {
- Object object = new Object();
- Object[] objArr = new Object[1000];
- }
- }
当运行至 Object[] objArr = new Object[1000]; 这句时, 如果内存不足, JVM 会抛出 OOM 错误也不会回收 object 指向的对象不过要注意的是, 当 fun1 运行完之后, object 和 objArr 都已经不存在了, 所以它们指向的对象都会被 JVM 回收
如果想中断强引用和某个对象之间的关联, 可以显示地将引用赋值为 null, 这样一来的话, JVM 在合适的时间就会回收该对象
软引用(SoftReference)
软引用是用来描述一些有用但并不是必需的对象, 在 Java 中用 java.lang.ref.SoftReference 类来表示对于软引用关联着的对象, 只有在内存不足的时候 JVM 才会回收该对象因此, 这一点可以很好地用来解决 OOM 的问题, 并且这个特性很适合用来实现缓存: 比如网页缓存图片缓存等
软引用可以和一个引用队列 (ReferenceQueue) 联合使用, 如果软引用所引用的对象被 JVM 回收, 这个软引用就会被加入到与之关联的引用队列中下面是一个使用示例:
- import java.lang.ref.WeakReference;
- public class Main {
- public static void main(String[] args) {
- WeakReference sr = new WeakReference(new String("hello"));
- System.out.println(sr.get());
- System.gc(); // 通知 JVM 的 gc 进行垃圾回收
- System.out.println(sr.get());
- }
- }
弱引用(WeakReference)
弱引用也是用来描述非必需对象的, 当 JVM 进行垃圾回收时, 无论内存是否充足, 都会回收被弱引用关联的对象在 java 中, 用 java.lang.ref.WeakReference 类来表示下面是使用示例:
- import java.lang.ref.WeakReference;
- public class Main {
- public static void main(String[] args) {
- WeakReference sr = new WeakReference(new String("hello"));
- System.out.println(sr.get());
- System.gc(); // 通知 JVM 的 gc 进行垃圾回收
- System.out.println(sr.get());
- }
- }
虚引用(PhantomReference)
虚引用和前面的软引用弱引用不同, 它并不影响对象的生命周期在 java 中用 java.lang.ref.PhantomReference 类表示如果一个对象与虚引用关联, 则跟没有引用与之关联一样, 在任何时候都可能被垃圾回收器回收
要注意的是, 虚引用必须和引用队列关联使用, 当垃圾回收器准备回收一个对象时, 如果发现它还有虚引用, 就会把这个虚引用加入到与之 关联的引用队列中程序可以通过判断引用队列中是否已经加入了虚引用, 来了解被引用的对象是否将要被垃圾回收如果程序发现某个虚引用已经被加入到引用队列, 那么就可以在所引用的对象的内存被回收之前采取必要的行动
进一步理解软引用和弱引用
对于强引用, 我们平时在编写代码时经常会用到而对于其他三种类型的引用, 使用得最多的就是软引用和弱引用, 这 2 种既有相似之处又有区别它们都是用来描述非必需对象的, 但是被软引用关联的对象只有在内存不足时才会被回收, 而被弱引用关联的对象在 JVM 进行垃圾回收时总会被回收针对上面的特性, 软引用适合用来进行缓存, 当内存不够时能让 JVM 回收内存, 弱引用能用来在回调函数中防止内存泄露因为回调函数往往是匿名内部类, 隐式保存有对外部类的引用, 所以如果回调函数是在另一个线程里面被回调, 而这时如果需要回收外部类, 那么就会内存泄露, 因为匿名内部类保存有对外部类的强引用
来源: http://www.bubuko.com/infodetail-2522827.html