最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入了解JAVA 虛引用

 更新時間:2020年08月17日 15:44:52   作者:弗蘭克的貓  
這篇文章主要介紹了JAVA 虛引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)JAVA,感興趣的朋友可以了解下

定義

虛引用是使用PhantomReference創(chuàng)建的引用,虛引用也稱為幽靈引用或者幻影引用,是所有引用類型中最弱的一個。一個對象是否有虛引用的存在,完全不會對其生命周期構(gòu)成影響,也無法通過虛引用獲得一個對象實例。

說明

虛引用,正如其名,對一個對象而言,這個引用形同虛設(shè),有和沒有一樣。

如果一個對象與GC Roots之間僅存在虛引用,則稱這個對象為虛可達(dá)(phantom reachable)對象。

當(dāng)試圖通過虛引用的get()方法取得強(qiáng)引用時,總是會返回null,并且,虛引用必須和引用隊列一起使用。既然這么虛,那么它出現(xiàn)的意義何在??

別慌別慌,自然有它的用處。它的作用在于跟蹤垃圾回收過程,在對象被收集器回收時收到一個系統(tǒng)通知。 當(dāng)垃圾回收器準(zhǔn)備回收一個對象時,如果發(fā)現(xiàn)它還有虛引用,就會在垃圾回收后,將這個虛引用加入引用隊列,在其關(guān)聯(lián)的虛引用出隊前,不會徹底銷毀該對象。 所以可以通過檢查引用隊列中是否有相應(yīng)的虛引用來判斷對象是否已經(jīng)被回收了。

如果一個對象沒有強(qiáng)引用和軟引用,對于垃圾回收器而言便是可以被清除的,在清除之前,會調(diào)用其finalize方法,如果一個對象已經(jīng)被調(diào)用過finalize方法但是還沒有被釋放,它就變成了一個虛可達(dá)對象。

與軟引用和弱引用不同,顯式使用虛引用可以阻止對象被清除,只有在程序中顯式或者隱式移除這個虛引用時,這個已經(jīng)執(zhí)行過finalize方法的對象才會被清除。想要顯式的移除虛引用的話,只需要將其從引用隊列中取出然后扔掉(置為null)即可。

同樣來看一個栗子:

public class PhantomReferenceTest {
 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");
 PhantomReference<TestClass> phantomReference = new PhantomReference<>(obj, QUEUE);

 // 該線程不斷讀取這個虛引用,并不斷往列表里插入數(shù)據(jù),以促使系統(tǒng)早點進(jìn)行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(phantomReference.get());
  }
 }).start();

 // 這個線程不斷讀取引用隊列,當(dāng)弱引用指向的對象唄回收時,該引用就會被加入到引用隊列中
 new Thread(() -> {
  while (true) {
  Reference<? extends TestClass> poll = QUEUE.poll();
  if (poll != null) {
   System.out.println("--- 虛引用對象被jvm回收了 ---- " + poll);
   System.out.println("--- 回收對象 ---- " + poll.get());
  }
  }
 }).start();

 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() {
  return "TestClass - " + name;
 }
 }
}

使用的虛擬機(jī)設(shè)置如下:

-verbose:gc -Xms4m -Xmx4m -Xmn2m

運行結(jié)果如下:

[GC (Allocation Failure) 1024K->432K(3584K), 0.0113386 secs]
[GC (Allocation Failure) 1455K->520K(3584K), 0.0133610 secs]
[GC (Allocation Failure) 1544K->648K(3584K), 0.0008654 secs]
null
null
null
[GC (Allocation Failure) 1655K->973K(3584K), 0.0008111 secs]
null
...省略幾個null的輸出
[GC (Allocation Failure) 1980K->1997K(3584K), 0.0009289 secs]
[Full GC (Ergonomics) 1997K->1870K(3584K), 0.0048483 secs]
--- 弱引用對象被jvm回收了 ---- java.lang.ref.PhantomReference@74cbe23d
--- 回收對象 ---- null
null
...省略幾個null和幾次Full GC的輸出
[Full GC (Ergonomics) 2971K->2971K(3584K), 0.0024850 secs]
[Full GC (Allocation Failure) 2971K->2971K(3584K), 0.0022460 secs]
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at weakhashmap.PhantomReferenceTest.lambda$main$0(PhantomReferenceTest.java:20)
at weakhashmap.PhantomReferenceTest$$Lambda$1/2065951873.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)

因為設(shè)置的虛擬機(jī)堆大小比較小,所以創(chuàng)建一個100k的對象時直接進(jìn)入了老年代,等到發(fā)生Full GC時才會被掃描然后回收。

適用場景

使用虛引用的目的就是為了得知對象被GC的時機(jī),所以可以利用虛引用來進(jìn)行銷毀前的一些操作,比如說資源釋放等。這個虛引用對于對象而言完全是無感知的,有沒有完全一樣,但是對于虛引用的使用者而言,就像是待觀察的對象的把脈線,可以通過它來觀察對象是否已經(jīng)被回收,從而進(jìn)行相應(yīng)的處理。

事實上,虛引用有一個很重要的用途就是用來做堆外內(nèi)存的釋放,DirectByteBuffer就是通過虛引用來實現(xiàn)堆外內(nèi)存的釋放的。

小結(jié)

  • 虛引用是最弱的引用
  • 虛引用對對象而言是無感知的,對象有虛引用跟沒有是完全一樣的
  • 虛引用不會影響對象的生命周期
  • 虛引用可以用來做為對象是否存活的監(jiān)控

以上就是詳解JAVA 虛引用的詳細(xì)內(nèi)容,更多關(guān)于JAVA 虛引用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的RestTemplate使用詳解

    Java中的RestTemplate使用詳解

    這篇文章主要介紹了Java中的RestTemplate使用詳解,Spring內(nèi)置了RestTemplate作為Http請求的工具類,簡化了很多操作,雖然Spring5推出了WebClient,但是整體感覺還是RestTemplate用起來更簡單方便一些,需要的朋友可以參考下
    2023-10-10
  • 詳解Spring Cloud中Hystrix的請求合并

    詳解Spring Cloud中Hystrix的請求合并

    這篇文章主要介紹了詳解Spring Cloud中Hystrix的請求合并,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • java?Object的hashCode方法的計算邏輯分析

    java?Object的hashCode方法的計算邏輯分析

    這篇文章主要介紹了java?Object的hashCode方法的計算邏輯分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 詳解如何使用MongoDB+Springboot實現(xiàn)分布式ID的方法

    詳解如何使用MongoDB+Springboot實現(xiàn)分布式ID的方法

    這篇文章主要介紹了詳解如何使用MongoDB+Springboot實現(xiàn)分布式ID的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 淺談Java循環(huán)中的For和For-each哪個更快

    淺談Java循環(huán)中的For和For-each哪個更快

    本文主要介紹了淺談Java循環(huán)中的For和For-each哪個更快,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • IDEA 單元測試覆蓋技巧分享

    IDEA 單元測試覆蓋技巧分享

    這篇文章主要介紹了IDEA 單元測試覆蓋技巧分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java設(shè)計模式之中介者模式

    Java設(shè)計模式之中介者模式

    這篇文章介紹了Java設(shè)計模式之中介者模式,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • 鏈表的原理及java實現(xiàn)代碼示例

    鏈表的原理及java實現(xiàn)代碼示例

    這篇文章主要介紹了鏈表的原理及java實現(xiàn)代碼示例,涉及單向鏈表的基本介紹,單向鏈表的Java實現(xiàn)代碼分享等相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以參考下。
    2017-11-11
  • Java之SpringBoot集成ActiveMQ消息中間件案例講解

    Java之SpringBoot集成ActiveMQ消息中間件案例講解

    這篇文章主要介紹了Java之SpringBoot集成ActiveMQ消息中間件案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 教你輕松制作java音樂播放器

    教你輕松制作java音樂播放器

    這篇文章主要介紹了如何編寫屬于自己的java音樂播放器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10

最新評論

开远市| 泸州市| 穆棱市| 巴林右旗| 儋州市| 景谷| 舞钢市| 家居| 嘉义市| 台南县| 秀山| 佛学| 银川市| 黄大仙区| 长兴县| 临安市| 瑞安市| 莱州市| 抚远县| 阳原县| 伊通| 布尔津县| 余庆县| 贵港市| 海宁市| 河北区| 六枝特区| 遵化市| 吉木乃县| 吉首市| 南通市| 肃南| 兴业县| 辉县市| 闽清县| 新乐市| 广宁县| 谷城县| 新竹县| 博爱县| 公主岭市|