Java內存管理再探究

VSITren 8年前發布 | 7K 次閱讀 Java開發

來自: http://blog.csdn.net/tryitboy/article/details/50551523


以前寫過JVM及內存管理的文章,現在看來,當時對Java虛擬機及其內存管理的方式還是認識不夠深。今天結合書本再次做個整理。


來源

“垃圾回收”機制很容易理解。Java語言在創建對象的時候回占用內存,作為一種自我保護,避免內存泄露,Java提供了垃圾回收機制來回收不再使用的對象所占用的內存空間。


內存分配方式

關于Java常用虛擬機內存的分配,請參見以前的博文:點這里哦
Java虛擬機將自己分配的對象或者數組存儲在某種數據結構中,簡稱這種數據結構為“分配表”。同時JVM還能區分棧幀里的局部變量指向堆里的哪一個對象或者數組。Finally,JVM能夠追蹤到堆中對象和數組保存的引用。
因為上述特性,JVM已經能夠判斷內存分配的對象在某個時刻是否依舊被對象或變量引用。在遇到不被引用的對象時,解釋器就可以回收這個對象的內存。


基本標記算法

通常垃圾回收使用的方式叫做“標記算法”。顧名思義,就是把不再占用內存的對象標記出來,一一清除。具體過程如下:

  1. 迭代分配表,把所有的對象都標記為死亡。
  2. 從指向堆的局部變量開始,每次遇到對象,沿著對象的引用一直向下,每次遇到分配表中沒有的對象或數組,就標記為存活(這就是標記算法)。一直向下,直到找出能從局部變量到達的所有引用為止。
  3. 再次執行第一步,迭代分配表。這次回收所有標記為死亡的對象占用的內存,同時釋放內存,刪除這些死亡對象。

    但是同時JVM面臨一個問題,就是在回收過程中,應用程序可能一直在執行,所以回收執行前后的對象狀態不一定一致,某個對象在回收前可能是活躍的,在回收執行之后也恰好不活躍了,這怎么處理?
    此時JVM也有優化機制。就是在執行回收時,應用程序進行短暫停頓(stop the world,STW),這個停頓不會影響到程序的正常執行。停頓之后,進行垃圾回收,然后繼續執行應用程序。

    </li> </ol>


    弱代假設(Weak Generational Hypothesis)

    然而,在實際的運行環境中,對象的狀態不是均勻分布的。通常大部分對象在創建之后很早就不再被使用;同時對于舊的對象,也很少引用新的對象。因此在這里,可以將堆分成存放舊對象和新對象的不同區域,也就是常說的老年代和新生代(這就是新生代和老年代的由來,說到底還是為了方便垃圾回收)。


    復制回收算法

    此時就可以用復制算法了,也叫篩選算法
    來看下文軒網技術團隊的筆記:

    由于新生代對象98%都是朝生夕死,故采用復制算法回收效率最高,將新生代分為一塊Eden,二塊Survivor區域
    Eden區域用于新對象的內存分配。Eden內存分配采用bump-the-pointer技術,使用一個指針指向已分配內存的末尾,分配內存時,僅檢查剩余內存是否滿足新對象分配。效率高。對于多線程內存分配采用Thread-Local Allocation Buffers TLABS,每個線程有自己的一塊空閑內存分配緩沖區。不需要任何鎖機制,只有當一個TLAB滿了以后才需要同步。
    兩塊Survivor區域分為From和To,To區域用于下次新生代GC存活對象的存放地,From區域存放著至少活過一次新生代GC的對象。在一次新生代GC結束后,From變為To,To變為From。原文地址

    </blockquote>

    上文說得很明顯,這種復制算法的主要工作就是復制存活的對象,所以至始至終它處理的是活性對象,效率更高。新生代的Eden部分存放新對象,Survivor部分不停地變換From和To。此時如果存在好幾次變換后依舊活著的對象,直接移到老年代(老不死的對象…)。
    此外還有持久代,主要存放類信息什么的(類定義,結構,字段,方法(數據及代碼)以及常量在內的類相關數據),和垃圾回收關系不大。而且在Java 8中,持久代已經廢棄,取而代之的是元空間(metaspace),參見:Java 8的元空間Java 8: 從永久代(PermGen)到元空間(Metaspace)

    到這里Java的內存管理差不多總結完了,如果你還想了解其他的垃圾回收算法,推薦閱讀這篇文字:幾種經典的垃圾回收算法


    FYI:

    http://www.baiduhome.net/lib/view/open1413872607965.html
    http://blog.jobbole.com/80499/
    http://developers.winxuan.com/blog/434
    http://my.oschina.net/hnuweiwei/blog/291367?p=1

    </blockquote> </div>

 本文由用戶 VSITren 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!