成人视屏在线观看-国产99精品-国产精品1区2区-欧美一级在线观看-国产一区二区日韩-色九九九

您的位置:首頁技術(shù)文章
文章詳情頁

深入了解JAVA 虛引用

瀏覽:10日期:2022-08-27 08:44:34

定義

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

說明

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

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

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

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

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

與軟引用和弱引用不同,顯式使用虛引用可以阻止對象被清除,只有在程序中顯式或者隱式移除這個虛引用時,這個已經(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)早點進行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(); // 這個線程不斷讀取引用隊列,當弱引用指向的對象唄回收時,該引用就會被加入到引用隊列中 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; } }}

使用的虛擬機設(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]nullnullnull[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--- 回收對象 ---- nullnull...省略幾個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 spaceat 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è)置的虛擬機堆大小比較小,所以創(chuàng)建一個100k的對象時直接進入了老年代,等到發(fā)生Full GC時才會被掃描然后回收。

適用場景

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

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

小結(jié)

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

以上就是詳解JAVA 虛引用的詳細內(nèi)容,更多關(guān)于JAVA 虛引用的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 欧美特欧美特级一片 | 久久久免费观看 | 亚洲欧美高清视频 | 黄色三级网站在线观看 | 久久久一区二区三区不卡 | 99久久精品免费看国产免费 | 国产精品视频网址 | 美美女高清毛片视频免费观看 | 国产欧美日韩一区 | 日日撸夜夜操 | 亚洲精品国产第一区第二区国 | 精品无码一区在线观看 | 欧美一区二区三区国产精品 | 欧美成在人线a免费 | 国产成人免费视频 | 久久国产精品岛国搬运工 | 国产无卡一级毛片aaa | 亚洲视屏在线 | 精品国产亚洲人成在线 | 成人在线不卡视频 | 中文字幕日韩三级 | 国产九九在线观看播放 | 国产成人综合亚洲 | 成人在线视频国产 | 一级aaaaaa毛片免费同男同女 | 久久久国产精品网站 | 日韩a级| 久草手机在线视频 | 日韩 国产 欧美 | 日韩精品一区二区三区中文在线 | 国产真真人女人特级毛片 | 中文乱码字幕午夜无线观看 | 三级全黄a| 国产精品久久久久久久久久久搜索 | 国产色在线播放 | 国产精品视频第一区二区三区 | 成人免费视频一区二区 | 亚洲国产精品综合久久一线 | 欧美日韩精品国产一区在线 | 国产三级国产精品国产普男人 | 99在线视频精品费观看视 |