<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 中的 "弱" 引用有啥用?

          共 3851字,需瀏覽 8分鐘

           ·

          2021-01-09 18:28

          Java技術(shù)棧

          www.javastack.cn

          關(guān)注閱讀更多優(yōu)質(zhì)文章



          作者:telami
          來(lái)源:www.telami.cn/2017/weak-reference/

          推薦閱讀:Java 強(qiáng)、弱、軟、虛,你屬于哪一種?

          Java里一個(gè)對(duì)象obj被創(chuàng)建時(shí),被放在堆里。當(dāng)GC運(yùn)行的時(shí)候,發(fā)現(xiàn)沒(méi)有任何引用指向obj,那么就會(huì)回收obj對(duì)象的堆內(nèi)存空間。

          換句話(huà)說(shuō),一個(gè)對(duì)象被回收, 必須滿(mǎn)足兩個(gè)條件:

          (1)沒(méi)有任何引用指向它

          (2)GC被運(yùn)行。

          在實(shí)際開(kāi)發(fā)中,我們可以通過(guò)把所有指向某個(gè)對(duì)象的referece置空來(lái)保證這個(gè)對(duì)象在下次GC運(yùn)行的時(shí)候被回收,類(lèi)似下面:

          Object?c?=?new?Car();????
          c=null;

          但是,這樣做是一件很繁瑣并且違背GC自動(dòng)回收原則的事。對(duì)于簡(jiǎn)單的情況, 手動(dòng)置空是不需要程序員來(lái)做的, 因?yàn)樵趈ava中, 對(duì)于簡(jiǎn)單對(duì)象, 當(dāng)調(diào)用它的方法執(zhí)行完畢后, 指向它的引用會(huì)被從棧中彈出, 所以它就能在下一次GC執(zhí)行時(shí)被回收了。

          但是, 也有特殊例外. 當(dāng)使用cache的時(shí)候, 由于cache的對(duì)象正是程序運(yùn)行需要的, 那么只要程序正在運(yùn)行, cache中的引用就不會(huì)被GC(或者說(shuō), cache中的reference擁有了和主程序一樣的life cycle). 那么隨著cache中的reference越來(lái)越多, GC無(wú)法回收的object也越來(lái)越多, 無(wú)法被自動(dòng)回收。當(dāng)這些object需要被回收時(shí), 回收這些object的任務(wù)只有交給程序編寫(xiě)者了。然而這卻違背了GC的本質(zhì)(自動(dòng)回收可以回收的objects)。

          所以, java中引入了weak reference。

          Object?c?=?new?Car();?//只要c還指向car?object,?car?object就不會(huì)被回收?-->(強(qiáng)引用)

          當(dāng)一個(gè)對(duì)象僅僅被weak reference指向, 而沒(méi)有任何其他strong reference指向的時(shí)候, 如果GC運(yùn)行, 那么這個(gè)對(duì)象就會(huì)被回收。另外,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):面試,可以獲取我整理的 JVM 系列面試題和答案,非常齊全。

          下面這個(gè)是網(wǎng)上的例子,首先定義一個(gè)實(shí)體類(lèi):

          public?class?Car?{
          ????private?double?????price;
          ????private?String????color;

          ????public?Car(double?price,?String?color)
          ????{
          ????????this.price?=?price;
          ????????this.color?=?color;
          ????}

          ????public?double?getPrice()
          ????{
          ????????return?price;
          ????}

          ????public?String?getColor()
          ????{
          ????????return?color;
          ????}

          ????public?String?toString()
          ????{
          ????????return?"This?car?is?a?"?+?this.color?+?"?car,?costs?$"?+?price;
          ????}
          }

          一般使用WeakReference的時(shí)候都會(huì)定義一個(gè)類(lèi)繼承自WeakReference,在這個(gè)類(lèi)中再定義一些別的屬性,這里就不定義別的屬性了:

          public?class?WeakReferenceCar?extends?WeakReference
          {
          ????public?WeakReferenceCar(Car?car)
          ????{
          ????????super(car);
          ????}
          }

          main函數(shù)調(diào)用一下,當(dāng)然為了更清楚地看到GC的效果,設(shè)置虛擬機(jī)參數(shù)”-XX:+PrintGCDetails”:

          public?static?void?main(String[]?args)
          {
          ????Car?car?=?new?Car(2000.0,?"red");
          ????WeakReferenceCar?wrc?=?new?WeakReferenceCar(car);
          ????wrc.setStr("111");
          ????int?i?=?0;
          ????while?(true)
          ????{
          ????????if?(wrc.get()?!=?null)
          ????????{
          ????????????i++;
          ????????????System.out.println("WeakReferenceCar's?Car?is?alive?for?"?+?i?+?",?loop?-?"?+?wrc);
          ????????}
          ????????else
          ????????{
          ????????????System.out.println("WeakReferenceCar's?Car?has?bean?collected");
          ????????????break;
          ????????}
          ????}
          }

          最后是運(yùn)行結(jié)果:

          WeakReferenceCar's?Car?is?alive?for?68450,?loop?-?interview.WeakReferenceCar@776ec8df
          WeakReferenceCar'
          s?Car?is?alive?for?68451,?loop?-?interview.WeakReferenceCar@776ec8df
          WeakReferenceCar's?Car?is?alive?for?68452,?loop?-?interview.WeakReferenceCar@776ec8df
          WeakReferenceCar'
          s?Car?is?alive?for?68453,?loop?-?interview.WeakReferenceCar@776ec8df
          [GC?(Allocation?Failure)?[PSYoungGen:?34304K->1000K(38400K)]?34320K->1016K(125952K),?0.0015129?secs]?[Times:?user=0.02?sys=0.02,?real=0.00?secs]?
          WeakReferenceCar's?Car?is?alive?for?68454,?loop?-?interview.WeakReferenceCar@776ec8df
          WeakReferenceCar'
          s?Car?has?bean?collected
          Heap
          PSYoungGen??????total?38400K,?used?1986K?[0x00000000d5e00000,?0x00000000da900000,?0x0000000100000000)
          eden?space?33280K,?2%?used?[0x00000000d5e00000,0x00000000d5ef6b70,0x00000000d7e80000)
          from?space?5120K,?19%?used?[0x00000000d7e80000,0x00000000d7f7a020,0x00000000d8380000)
          to???space?5120K,?0%?used?[0x00000000da400000,0x00000000da400000,0x00000000da900000)
          ParOldGen???????total?87552K,?used?16K?[0x0000000081a00000,?0x0000000086f80000,?0x00000000d5e00000)
          object?space?87552K,?0%?used?[0x0000000081a00000,0x0000000081a04000,0x0000000086f80000)
          Metaspace???????used?3547K,?capacity?4564K,?committed?4864K,?reserved?1056768K
          class?space????used?381K,?capacity?388K,?committed?512K,?reserved?1048576K

          可以看到在68454循環(huán)之后,WeakReferenceCar關(guān)聯(lián)的對(duì)象Car被回收掉了,注意是弱引用關(guān)聯(lián)的對(duì)象car被回收,而不是弱引用本身wrc被回收。

          WeakReference的一個(gè)特點(diǎn)是它何時(shí)被回收是不可確定的, 因?yàn)檫@是由GC運(yùn)行的不確定性所確定的. 所以, 一般用weak reference引用的對(duì)象是有價(jià)值被cache, 而且很容易被重新被構(gòu)建, 且很消耗內(nèi)存的對(duì)象.

          在weak reference指向的對(duì)象被回收后, weak reference本身其實(shí)也就沒(méi)有用了. java提供了一個(gè)ReferenceQueue來(lái)保存這些所指向的對(duì)象已經(jīng)被回收的reference. 用法是在定義WeakReference的時(shí)候?qū)⒁粋€(gè)ReferenceQueue的對(duì)象作為參數(shù)傳入構(gòu)造函數(shù)。






          關(guān)注Java技術(shù)棧看更多干貨



          戳原文,獲取精選面試題!
          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久妻视频免费精品人妻中文无码 | 亚洲无码三级电影 | 青青草免费在线公开视频播放 | 婷婷久久综合 | 逼逼网 |