国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java 詳解垃圾回收與對(duì)象生命周期

2019-11-26 13:15:34
字體:
供稿:網(wǎng)友

Java 垃圾回收與對(duì)象生命周期詳解

Java中的垃圾回收與對(duì)象生命周期

1. 垃圾回收

   垃圾回收是Java程序設(shè)計(jì)中內(nèi)存管理的核心概念,JVM的內(nèi)存管理機(jī)制被稱為垃圾回收機(jī)制。

  一個(gè)對(duì)象創(chuàng)建后被放置在JVM的堆內(nèi)存中,當(dāng)永遠(yuǎn)不再引用這個(gè)對(duì)象時(shí),它將被JVM在堆內(nèi)存中回收。被創(chuàng)建的對(duì)象不能再生,同時(shí)也沒有辦法通過程序語句釋放它們。即當(dāng)對(duì)象在JVM運(yùn)行空間中無法通過根集合到達(dá)(找到)時(shí),這個(gè)對(duì)象被稱為垃圾對(duì)象。根集合是由類中的靜態(tài)引用域與本地引用域組成的。JVM通過根集合索引對(duì)象。

    在做Java應(yīng)用開發(fā)時(shí)經(jīng)常會(huì)用到由JVM管理的兩種類型的內(nèi)存:堆內(nèi)存和棧內(nèi)存。簡單來講,堆內(nèi)存主要用來存儲(chǔ)程序在運(yùn)行時(shí)創(chuàng)建或?qū)嵗膶?duì)象與變量。例如通過new關(guān)鍵字創(chuàng)建的對(duì)象。而棧內(nèi)存則是用來存儲(chǔ)程序代碼中聲明為靜態(tài)或非靜態(tài)的方法。

(1) 堆內(nèi)存

    堆內(nèi)存在JVM啟動(dòng)的時(shí)候被創(chuàng)建,堆內(nèi)存中所存儲(chǔ)的對(duì)象可以被JVM自動(dòng)回收,不能通過其他外部手段回收,也就是說開發(fā)人員無法通過添加相關(guān)代碼的手段來回收堆內(nèi)存中的對(duì)象。堆內(nèi)存通常情況下被分為兩個(gè)區(qū)域:新對(duì)象區(qū)域與老對(duì)象區(qū)域。

    新對(duì)象區(qū)域:又可細(xì)分為三個(gè)小區(qū)域:伊甸園區(qū)域、From區(qū)域與To區(qū)域。伊甸園區(qū)域用來保存新創(chuàng)建的對(duì)象,它就像一個(gè)堆棧,新的對(duì)象被創(chuàng)建,就像指向該棧的指針在增長一樣,當(dāng)伊甸園區(qū)域中的對(duì)象滿了之后,JVM系統(tǒng)將要做到可達(dá)性測試,主要任務(wù)是檢測有哪些對(duì)象由根集合出發(fā)是不可達(dá)的,這些對(duì)象就可以被JVM回收,并且將所有的活動(dòng)對(duì)象從伊甸園區(qū)域拷貝到To區(qū)域,此時(shí)一些對(duì)象將發(fā)生狀態(tài)交換,有的對(duì)象就從To區(qū)域被轉(zhuǎn)移到From區(qū)域,此時(shí)From區(qū)域就有了對(duì)象。上面對(duì)象遷移的整個(gè)過程,都是由JVM控制完成的。

    老對(duì)象區(qū)域:在老對(duì)象區(qū)域中的對(duì)象仍然會(huì)有一個(gè)較長的生命周期,大多數(shù)的JVM系統(tǒng)垃圾對(duì)象,都是源于"短命"對(duì)象,經(jīng)過一段時(shí)間后,被轉(zhuǎn)入老對(duì)象區(qū)域的對(duì)象,就變成了垃圾對(duì)象。此時(shí),它們都被打上相應(yīng)的標(biāo)記,JVM系統(tǒng)將會(huì)自動(dòng)回收這些垃圾對(duì)象,建議不要頻繁地強(qiáng)制系統(tǒng)作垃圾回收,這是因?yàn)镴VM會(huì)利用有限的系統(tǒng)資源,優(yōu)先完成垃圾回收工作,導(dǎo)致應(yīng)用無法快速地響應(yīng)來自用戶端的請(qǐng)求,這樣會(huì)影響系統(tǒng)的整體性能。

(2) 棧內(nèi)存

    堆內(nèi)存主要用來存儲(chǔ)程序在運(yùn)行時(shí)創(chuàng)建或?qū)嵗膶?duì)象與變量。例如通過new關(guān)鍵字創(chuàng)建的對(duì)象。而棧內(nèi)存則是用來存儲(chǔ)程序代碼中聲明為靜態(tài)或非靜態(tài)的方法。

2. JVM中對(duì)象的生命周期

   在JVM運(yùn)行空間中,對(duì)象的整個(gè)生命周期大致可以分為7個(gè)階段: 

  •    創(chuàng)建階段;
  •    應(yīng)用階段;
  •    不可視階段;
  •    不可到達(dá)階段;
  •    可收集階段;
  •    終結(jié)階段;
  •    釋放階段 

   上面這7個(gè)階段,構(gòu)成了JVM中對(duì)象的完整的生命周期。

  (1) 創(chuàng)建階段

       在對(duì)象的創(chuàng)建階段,系統(tǒng)主要通過下面的步驟,完成對(duì)象的創(chuàng)建過程:      

       <1> 為對(duì)象分配存儲(chǔ)空間;
       <2> 開始構(gòu)造對(duì)象;
       <3> 從超類到子類對(duì)static成員進(jìn)行初始化;
       <4> 超類成員變量按順序初始化,遞歸調(diào)用超類的構(gòu)造方法;
       <5> 子類成員變量按順序初始化,子類構(gòu)造方法調(diào)用。

       在創(chuàng)建對(duì)象時(shí)應(yīng)注意幾個(gè)關(guān)鍵應(yīng)用規(guī)則:        

       <1> 避免在循環(huán)體中創(chuàng)建對(duì)象,即使該對(duì)象占用內(nèi)存空間不大。
       <2> 盡量及時(shí)使對(duì)象符合垃圾回收標(biāo)準(zhǔn)。比如 myObject = null。
       <3> 不要采用過深的繼承層次。
       <4> 訪問本地變量優(yōu)于訪問類中的變量。

 (2) 應(yīng)用階段

       在對(duì)象的引用階段,對(duì)象具備如下特征:

      <1> 系統(tǒng)至少維護(hù)著對(duì)象的一個(gè)強(qiáng)引用(Strong Reference); 

      <2> 所有對(duì)該對(duì)象的引用全部是強(qiáng)引用(除非我們顯示地適用了:軟引用(Soft Reference)、弱引用(Weak Reference)或虛引用(Phantom Reference)).

      強(qiáng)引用(Strong Reference):是指JVM內(nèi)存管理器從根引用集合出發(fā)遍歷堆中所有到達(dá)對(duì)象的路徑。當(dāng)?shù)竭_(dá)某對(duì)象的任意路徑都不含有引用對(duì)象時(shí),這個(gè)對(duì)象的引用就被稱為強(qiáng)引用。

       軟引用(Soft Reference):軟引用的主要特點(diǎn)是有較強(qiáng)的引用功能。只有當(dāng)內(nèi)存不夠的時(shí)候,才回收這類內(nèi)存,因此內(nèi)存足夠時(shí)它們通常不被回收。另外這些引用對(duì)象還能保證在Java拋出OutOfMemory異常之前,被設(shè)置為null。它可以用于實(shí)現(xiàn)一些常用資源的緩存,實(shí)現(xiàn)Cache功能,保證最大限度地使用內(nèi)存你而不引起OutOfMemory。

下面是軟引用的實(shí)現(xiàn)代碼:

                import java.lang.ref.SoftReference;                ...                                 A a = new A();                ...                 // 使用a                ...                                 // 使用完了a, 將它設(shè)置為soft引用類型,并且釋放強(qiáng)引用                SoftReference sr = new SoftReference(a);                a = null;                ...                 // 下次使用時(shí)          if (sr != null) {          a = sr.get();        } else {          // GC由于低內(nèi)存,已釋放a,因此需要重新裝載                  a = new A();          sr = new SoftReference(a);        } 

 軟引用技術(shù)的引進(jìn)使Java應(yīng)用可以更好地管理內(nèi)存,穩(wěn)定系統(tǒng),防止系統(tǒng)內(nèi)存溢出,避免系統(tǒng)崩潰。因此在處理一些占用內(nèi)存較大且生命周期較長,但使用并不繁地對(duì)象時(shí)應(yīng)盡量應(yīng)用該技術(shù)。提高系統(tǒng)穩(wěn)定性。                                                  

       弱引用(Weak Reference):弱應(yīng)用對(duì)象與軟引用對(duì)象的最大不同就在于:GC在進(jìn)行垃圾回收時(shí),需要通過算法檢查是否回收Soft應(yīng)用對(duì)象,而對(duì)于Weak引用,GC總是進(jìn)行回收。Weak引用對(duì)象更容易、更快地被GC回收。Weak引用對(duì)象常常用于Map結(jié)構(gòu)中。

import java.lang.ref.WeakReference;                  ...                                  A a = new A();                 ...                  // 使用a                 ...                                  // 使用完了a, 將它設(shè)置為Weak引用類型,并且釋放強(qiáng)引用                 WeakReference wr = new WeakReference(a);                 a = null;                  ...                 // 下次使用時(shí)         if (wr != null) {           a = wr.get();        } else {                    a = new A();          wr = new WeakReference(a);      } 

 虛引用(Phantom Reference): 虛引用的用途較少,主要用于輔助finalize函數(shù)的使用。

虛引用(Phantom Reference)對(duì)象指一些執(zhí)行完了finalize函數(shù),并為不可達(dá)對(duì)象,但是還沒有被GC回收的對(duì)象。這種對(duì)象可以輔助finalize進(jìn)行一些后期的回收工作,我們通過覆蓋了Refernce的clear()方法,增強(qiáng)資源回收機(jī)制的靈活性。

              在實(shí)際程序設(shè)計(jì)中一般很少使用弱引用和虛引用,是用軟引用的情況較多,因?yàn)檐浺每梢约铀貸VM對(duì)垃圾內(nèi)存的回收速度,可以維護(hù)系統(tǒng)的運(yùn)行安全,防止內(nèi)存溢出(OutOfMemory)等問題的產(chǎn)生。

    (3) 不可視階段 

         當(dāng)一個(gè)對(duì)象處于不可視階段,說明我們?cè)谄渌麉^(qū)域的代碼中已經(jīng)不可以在引用它,其強(qiáng)引用已經(jīng)消失,例如,本地變量超出了其可視
的范圍。

try {        Object localObj = new Object();    localObj.doSomething();     } catch (Exception e) {       e.printStackTrace();     }      if (true) {    // 此區(qū)域中l(wèi)ocalObj 對(duì)象已經(jīng)不可視了, 編譯器會(huì)報(bào)錯(cuò)。    localObj.doSomething();     } 

 (4) 不可到達(dá)階段 

       處于不可達(dá)階段的對(duì)象在虛擬機(jī)的對(duì)象引用根集合中再也找不到直接或間接地強(qiáng)引用,這些對(duì)象一般是所有線程棧中的臨時(shí)變量。所有已經(jīng)裝載的靜態(tài)變量或者是對(duì)本地代碼接口的引用。

   (5) 可收集階段、終結(jié)階段與釋放階段 

       當(dāng)一個(gè)對(duì)象處于可收集階段、終結(jié)階段與釋放階段時(shí),該對(duì)象有如下三種情況:

       <1> 回收器發(fā)現(xiàn)該對(duì)象已經(jīng)不可達(dá)。

       <2> finalize方法已經(jīng)被執(zhí)行。

       <3> 對(duì)象空間已被重用。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 上杭县| 兖州市| 连州市| 昌都县| 永靖县| 临澧县| 绥滨县| 左云县| 山东省| 博野县| 江永县| 黔南| 翁牛特旗| 北碚区| 北流市| 吉木萨尔县| 古田县| 阳曲县| 乌审旗| 任丘市| 安图县| 什邡市| 平泉县| 资兴市| 彭山县| 桦川县| 和静县| 巴林左旗| 溆浦县| 和平县| 黄陵县| 丰原市| 梅河口市| 延吉市| 云霄县| 新巴尔虎左旗| 体育| 来安县| 石嘴山市| 武功县| 湖北省|