變量:弱引用問題

背景

在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());
        }
      }
    });
  }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章