深刻理解 Java 虛擬機之學習筆記(3)

垃圾回收(Garbage Collection,GC ) ,GC的歷史其實比Java久遠,1960年誕生與MIT的Lisp是第一門真正使用內存動態分配和垃圾收集技術的語言。當Lisp還在胚胎時期時,人們就在思考GC須要完成的3件事情:
  • 哪些內存須要回收?
  • 何時回收?
  • 如何回收?
  :通過半個多世紀的發展,目前內存的動態分配與內存回收技術已經至關成熟,一切看起來都進入了「自動化」時代,爲什麼咱們還要去了解GC和內存分配呢?
  :當須要排查各類內存溢出、內存泄露問題時,當垃圾收集成爲系統達到更高併發量的瓶頸時,咱們就須要對這些「自動化」的技術實施必要的監控和調節。
 
  肯定GC回收的區域:
 
  (1)程序計數器、虛擬機棧、本地方法棧這3個區域隨線程而生,隨線程而滅。每個棧幀中分配多少內存基本上是在類結構肯定下來時就已知的,所以這幾個區域的內存分配和回收都具有肯定性,在這幾個區域內就不須要過多考慮回收的問題,由於方法結束或線程結束時,內存天然就跟着回收了。
 
  (2)Java堆(Heap)和方法區則不同,一個接口中的多個實現類須要的內存可能不同,一個方法中的多個分支須要的內存也可能不同,咱們只有在程序處於運行期間時才能知道會建立哪些對象,這部份內存的分配和回收都是動態的,垃圾收集器所關注的是這部份內存。 
 
1.判斷對象是否存活的算法之一:引用計數算法。
 
  算法思想以及應用分析:
 
  (1)給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任什麼時候刻計數器爲0的對象就是不可能再被使用的。
 
  (2)客觀地說,引用計數算法的實現簡單,斷定效率也很高,在大部分狀況下都是一個不錯的算法,也有一些著名的應用案例,例如微軟公司的COM(Component Object Model)技術、使用ActionScript 3的Flashplayer、Python語言和在遊戲腳本領域被普遍應用的Squirrel中都使用了引用計數算法進行內存管理。
 
  (3)可是主流的Java虛擬機裏面沒有選用引用計數算法來管理內存,其中最主要的緣由是它很難解決對象之間相互循環引用的問題。
 
2.針對對象之間相互循環引用的問題進行的實驗以下圖所示:
  
 
   從上面的運行結果能夠獲得,GC日誌中包含的「8028K->512K」,意味着虛擬機並無由於這兩個對象互相引用就不回收它們,這也從側面說明虛擬機並非經過引用計數算法來判斷對象是否存活的。
 
3.判斷對象是否存活的算法之一: 可達性分析算法。
 
  算法思想及應用:
 
  (1)這個算法基本思想就是經過一系列的成爲「GC Roots」的對象做爲起始點,從這些節點開始向下搜素,搜素所作過的路徑成爲引用鏈(Reference Chain)。當一個對象到GC Roots沒有任何引用鏈相連(圖論中爲從GC Root到這個對象不可達)時,則證實此對象是不可用的。以下圖所示:
  
   (2)在Java語言中,可做爲GC Roots的對象包括下面:
 
    a. 虛擬機棧(棧幀中的本地變量表)中引用的對象。

    b.方法區中類靜態屬性引用的對象。算法

    c.方法區中常量引用的對象。併發

    d.本地方法棧中JNI(Native 方法)引用的方法。高併發

 

    (3)在主流的商用程序語言(Java、C#,甚至包括前面提到的古老的Lisp)的主流實現中,都是稱經過可達性分析(Reachability Analysis)來斷定對象是否存活的。
 
4. 再談引用
 
  引用的定義:在JDK 1.2之前,Java中的引用定義很傳統:若是reference類型的數據存儲的數值表明的是另一塊內存的起始地址,就稱這塊內存表明着一個引用。
 
    問題出現了:當描述這樣的一類對象:當內存空間還足夠時,則能保留在內存之中,若是內存空間在進行垃圾收集後仍是很是緊張,則能夠拋棄這些對象。此時的引用就顯得過於狹隘。所以在JDK 1.2以後,Java堆引用的概念進行了擴充。
 
   
強引用 Strong Reference 相似Object obj = new Object() 只要強引用還存在,垃圾收集器永遠不會回收掉被引用的對象
軟引用 Soft Reference 描述一些還有用但並不是必須的對象 在系統將要發生內存溢出的異常以前,將會把這些對象列進回收範圍之中進行第二次回收。若是此次回收尚未足夠的內存,纔會拋出內存溢出異常
弱引用 Wear Reference 用來描述非必須對象,強度比軟引用更弱。被弱引用關聯的對象只能生存到下一次垃圾收集發生以前 當垃圾收集器工做時,不管當前內存是否足夠,都會回收掉紙杯弱引用關聯的對象
虛引用 Phantom Reference 又稱爲幽靈引用或幻影引用,最弱的一種引用關係。一個對象是否有虛引用的存在,徹底不會對其生存時間構成影響,也沒法經過虛引用來取得一個對象實例。 爲一個對象設置虛引用關聯的衛衣目的就是能在這個對象被收集器回收時收到一個系統通知
相關文章
相關標籤/搜索