面試高頻問題:java的強(qiáng)引用安接、軟引用翔忽、弱引用、虛引用盏檐?

背景

面試官:什么是強(qiáng)引用歇式、軟引用、弱引用胡野、虛引用材失?

我說

java中為了控制對象的生命周期,在jdk1.2之后引入了強(qiáng)引用硫豆、軟引用龙巨、弱引用、虛引用來靈活地控制對象的生命周期熊响。

image-20200720163324083.png

強(qiáng)引用

強(qiáng)引用就是我們平時(shí)直接new出來的對象旨别,舉個栗子:Object strongReference = new Object();

所謂強(qiáng)引用,就是jvm寧愿拋出OOM也不愿意回收的對象(當(dāng)然是必須先是可達(dá)對象)汗茄,所以強(qiáng)引用是造成OOM的主要原因之一

image-20200720164058364.png

軟引用

軟引用就是被SoftReference修飾的對象秸弛,舉個栗子:SoftReference softObj = new SoftReference(new Object());

它會在發(fā)生gc的時(shí)候且內(nèi)存不足時(shí)進(jìn)行回收(回收的是引用的內(nèi)容,比如栗子中的new Object),所以軟引用適合用作緩存胆屿,在內(nèi)存充足的時(shí)候提示程序查詢效率奥喻,內(nèi)存不足時(shí)回收確保系統(tǒng)運(yùn)行正常

image-20200720165212324.png
弱引用

弱引用就是被WeakReference修飾的對象,舉個栗子:WeakReference weakR = new WeakReference<>(new Object());

它會在gc的時(shí)候被回收非迹,而不關(guān)心內(nèi)存是否充足

image.png

可以看到环鲤,強(qiáng)引用與軟引用在發(fā)生gc的時(shí)候都未被回收(軟引用由于不滿足內(nèi)存不足的條件),但是弱引用卻被回收了憎兽。像我們經(jīng)常用到的ThreadLocal就用到了弱引用冷离,用來防止內(nèi)存泄漏

虛引用

虛引用不同于其他三種引用,虛是形同虛設(shè)的虛纯命,相當(dāng)于沒有引用西剥,在任何時(shí)候都可能被回收。它不能單獨(dú)使用亿汞,也不能通過它訪問對象瞭空,并且必須和引用隊(duì)列(Reference queue)配合使用。

  • 虛引用的主要作用是跟蹤對象被垃圾回收的狀態(tài)疗我。僅僅是提供了一種確保對象被 finalize以后,做某些事情的機(jī)制咆畏。

  • PhantomReference的get方法總是返回null,因此無法訪問對應(yīng)的引用對象。

  • 使用它的意義在于說明一個對象已經(jīng)進(jìn)入 finalization階段,可以被回收,用來實(shí)現(xiàn)比 finalization機(jī)制更靈活的回收操作 換句話說,設(shè)置虛引用關(guān)聯(lián)的唯一目的,就是在這個對象被收集器回收的時(shí)候收到一個系統(tǒng)通知或者后續(xù)添加進(jìn)一步的處理吴裤;

  • 虛引用用來管理堆外內(nèi)存

    img
Reference queue引用隊(duì)列
  • 對象在被回收之前要被引用隊(duì)列保存一下旧找。GC之前對象不放在隊(duì)列中,GC之后才對象放入隊(duì)列中麦牺。

  • 【通過開啟線程監(jiān)聽該引用隊(duì)列的變化情況】就可以在對象被回收時(shí)采取相應(yīng)的動作钮蛛。 由于虛引用的唯一目的就是能在這個對象被垃圾收集器回收時(shí)能收到系統(tǒng)通知,因而創(chuàng)建虛引用時(shí)必須要關(guān)聯(lián)一個引用隊(duì)列剖膳,而軟引用和弱引用則不是必須的魏颓。 這里所謂的收到系統(tǒng)通知其實(shí)還是通過開啟線程監(jiān)聽該引用隊(duì)列的變化情況來實(shí)現(xiàn)的。

  • 這里還需要強(qiáng)調(diào)的是吱晒, 對于軟引用和弱引用琼开,當(dāng)執(zhí)行第一次垃圾回收時(shí),就會將軟引用或弱引用對象添加到其關(guān)聯(lián)的引用隊(duì)列中枕荞,然后其finalize函數(shù)才會被執(zhí)行(如果沒復(fù)寫則不會被執(zhí)行)柜候; 而對于虛引用,如果被引用對象沒有復(fù)寫finalize方法躏精,則是在第一垃圾回收將該類銷毀之后渣刷,才會將虛擬引用對象添加到引用隊(duì)列,如果被引用對象復(fù)寫了finalize方法矗烛,則是當(dāng)執(zhí)行完第二次垃圾回收之后辅柴,才會將虛引用對象添加到其關(guān)聯(lián)的引用隊(duì)列

  • 一個對象的finalize()方法只會被調(diào)用一次箩溃,而且finalize()被調(diào)用不意味著gc會立即回收該對象,所以有可能調(diào)用finalize()后碌嘀,該對象又不需要被回收了涣旨,然后到了真正要被回收的時(shí)候,因?yàn)榍懊嬲{(diào)用過一次股冗,所以不會調(diào)用finalize()霹陡,產(chǎn)生問題,所以,推薦不要使用finalize()方法

class User{
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("我要被GC干了止状!");
    }
}
 public static void main(String[] args) throws  Exception {
        User user=new User();
        ReferenceQueue<User> queue=new ReferenceQueue();
        PhantomReference prf=new PhantomReference(user,queue);

        //啟動一個線程監(jiān)控引用隊(duì)列的變化
        new Thread(()->{
            for(;;){
                final Reference<? extends User> u = queue.poll();
                if (u!=null){
                    System.out.println("有對象被加入到了引用隊(duì)列了烹棉!"+u);
                }
            }
        }).start();

        user=null;
        //GC之前引用隊(duì)列為空
        System.out.println("GC之前"+queue.poll());
        
        System.gc();
        Thread.sleep(100);
        //GC之后引用隊(duì)列才將對象放入
        System.out.println("第一次GC之后"+queue.poll());

        System.gc();
        Thread.sleep(100);
        System.out.println("第二次GC之后"+queue.poll());

    }


結(jié)果:

GC之前null
我要被GC干了!
第一次GC之后null
有對象被加入到了引用隊(duì)列了怯疤!java.lang.ref.PhantomReference@549763fd
第二次GC之后java.lang.ref.PhantomReference@5aaa6d82 

參考:https://www.cnblogs.com/wangsen/p/11206956.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浆洗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子集峦,更是在濱河造成了極大的恐慌伏社,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塔淤,死亡現(xiàn)場離奇詭異洛口,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凯沪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來买优,“玉大人妨马,你說我怎么就攤上這事∩庇” “怎么了烘跺?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脂崔。 經(jīng)常有香客問我滤淳,道長,這世上最難降的妖魔是什么砌左? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任脖咐,我火速辦了婚禮,結(jié)果婚禮上汇歹,老公的妹妹穿的比我還像新娘屁擅。我一直安慰自己,他們只是感情好产弹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布派歌。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胶果。 梳的紋絲不亂的頭發(fā)上匾嘱,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機(jī)與錄音早抠,去河邊找鬼霎烙。 笑死,一個胖子當(dāng)著我的面吹牛贝或,可吹牛的內(nèi)容都是我干的吼过。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼咪奖,長吁一口氣:“原來是場噩夢啊……” “哼盗忱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起羊赵,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤趟佃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后昧捷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闲昭,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年靡挥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了序矩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡跋破,死狀恐怖簸淀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毒返,我是刑警寧澤租幕,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站拧簸,受9級特大地震影響劲绪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盆赤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一贾富、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牺六,春花似錦祷安、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凉唐。三九已至,卻和暖如春霍骄,著一層夾襖步出監(jiān)牢的瞬間台囱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工读整, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留簿训,地道東北人。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓米间,卻偏偏與公主長得像强品,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屈糊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評論 2 349