变量:弱引用问题

原创
2023/03/07 17:32
阅读数 49

背景

在java中,存在4种引用关系,但是4种引用关系也有一些差异,这里主要讨论若引用和虚引用,但是一些细节点讨论:

  • API上有什么不同 ?
  • 虚引用和弱引用有什么不同?如果都是GC时都被回收,为什么不使用虚引用呢 ?
  • 引用实例的强引用释放之后,有什么不同?

解答:

  • 但是在gc上,他们很类似,但有有些区别,java 8.0之前,虚引用持有对象可能无法释放,因为为了通知对象将要被回收,虚引用会标记对象是激活状态,导致无法回收,java 8之后几乎完全一样,虚引用通知对象被回收在虚引用回收之后。
  • 产生时期不同

 

那么既然 java 8之后虚引用会被回收,为什么不使用虚引用而使用弱引用呢 ?

主要原因是虚引用的api决定了,get() 返回值是null

 

使用注意事项

常量:

    不要使用虚引用引用常量 (基本类型+字面量字符串),因为常量的生命周期相对较长

静态成员:

    不要引用静态成员,Class,因为这类成员生命周期也是很长

局部变量:

    不要引用局部变量,局部变量引用如果是异步+callback方式,很容易因为内存问题,导致局部变量提前被释放,造成不可控风险。

public static void main(String[] args){

final Logger log = new Logger("HaHaha");
testHttp(new WeakReference(log))
}


public void testHttp(WeakReference<Logger> ref){

okHttpClient.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        e.printStackTrace();
        Logger log =  ref.get(); //log可能提前为空
       
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        try (ResponseBody responseBody = response.body()) {
         Logger log =  ref.get(); //log可能提前为空
          if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

          Headers responseHeaders = response.headers();
          for (int i = 0, size = responseHeaders.size(); i < size; i++) {
            System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
          }

          System.out.println(responseBody.string());
        }
      }
    });
  }
}

 

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部