• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解 JAVA 弱引用

java 搞代码 4年前 (2022-01-09) 22次浏览 已收录 0个评论

定义

弱引用是使用WeakReference创建的引用,弱引用也是用来描述非必需对象的,它是比软引用更弱的引用类型。在发生GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。

说明

弱引用,从名字来看就很弱嘛,这种引用指向的对象,一旦在GC时被扫描到,就逃脱不了被回收的命运。

但是,弱引用指向的对象也并不一定就马上会被回收,如果弱引用对象较大,直接进到了老年代,那么就可以苟且偷生到Full GC触发前,所以弱引用对象也可能存在较长的一段时间。一旦一个弱引用对象被垃圾回收器回收,便会加入到一个引用队列中(如果有的话)。

弱引用对应的类为WeakReference,举个栗子:

String s = new String("Frank");  
WeakReference<String> weakRef = new WeakReference<String>(s);
s = null;

这里我们把s设置为null后,字符串对象便只有弱引用指向它。

弱可达

如果一个对象与GC Roots之间仅存在弱引用,则称这个对象为弱可达(weakly reachable)对象。

注意

在垃圾回收器回收一个对象前,WeakReference类所提供的get方法会返回其引用对象的强引用,一旦垃圾回收器回收掉该对象之后,get方法将返回null。所以在获取弱引用对象的代码中,一定要判断是否为null,以免出现NullPointerException异常导致应用崩溃。

下面的代码会让s再次持有对象的强引用:

s = weakRef.get();

如果在weakRef包裹的对象被回收前,用强引用关联该对象,那这个对象又会变成强可达状态。

来看一个简单的栗子了解一下WeakReference引用的对象是何时被回收的:

public class WeakReferenceTest {
  private static final List<Object> TEST_DATA = new LinkedList<>();
  private static final ReferenceQueue<TestClass> QUEUE = new ReferenceQueue<>();

  public static void main(String[] args) {
    TestClass obj = new TestClass("Test");
    WeakReference<TestClass> weakRef = new WeakReference<>(obj, QUEUE);
    //可以重新获得OOMClass对象,并用一个强引用指向它
    //oomObj = weakRef.get();

    // 该线程不断读取这个弱引用,并不断往列表里插入数据,以促使系统早点进行GC
    new Thread(() -> {
      while (true) {
        TEST_DATA.add(new byte[1024 * 100]);
        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
          Thread.currentThread().interrupt();
        }
        System.out.println(weakRef.get());
      }
    }).start();

    // 这个线程不断读取引用队列,当弱引用指向的对象呗回收时,该引用就会被加入到引用队列中
    new Thread(() -> {
      while (true) {
        Reference<? extends TestClass> poll = QUEUE.poll();
        if (poll != null) {
          System.out.println("--- 弱引用对象被jvm回收了 ---- " + poll);
          System.out.println("--- 回收对象 ---- " + poll.get());
        }
      }
    }).start();

    //将强引用指向空指针 那么此时只有一个弱引用指向TestClass对象
    obj = null;

    try {
      Thread.currentThread().join();
    } catch (InterruptedException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  static class TestClass {
    private String name;

    public TestClass(String name) {
      this.name = name;
    }

    @Override
    public String toString() {
      re<a>本文来源gao*daima.com搞@代#码&网6</a>turn "TestClass - " + name;
    }
  }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解 JAVA 弱引用

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址