提到Java的內存管理,我始終抱有一種又愛又恨的心理。做爲一門面向對象的高級語言,Java的確爲減輕程序員的負擔作出了巨大的努力,它的垃圾回收機制幫助百萬程序員從C系語言惱人的內存管理問題中解脫出來,成爲自身的一大亮點;但同時,垃圾回收機制的不可強制執行的特色,又讓瞭解過C/C++的人以爲自動垃圾回收反而是一種累贅,本身有管理內存的能力也不能施展,在必定程度上又限制了程序員的發揮。然而,Java又不可能由於這點就放棄本身的垃圾自動回收機制,因此,能改變的只有咱們本身了。程序員
「理想」的Java垃圾回收機制算法
Java是打着爲減輕程序員負擔的旗號而誕生的一種語言。在誕生之初,的確受到了百萬程序員的追捧。那麼,Java的垃圾回收機制到底是什麼樣的?一塊兒來看。併發
· Java垃圾回收機制算法高併發
首先,Java並無聲明JVM應該使用那種算法,全部的算法只是其回收機制可能採用的一種策略。這裏列舉兩種:線程
·1.引用計數法對象
·2.標記法內存
Java在早期的時候採用的一種策略是引用計數法,即目標對象在建立時默認有一個計數器,用來統計該對象身上的引用數目,當數目爲0時,代表沒有變量引用該對象,則對象可回收。而垃圾回收器也主要檢查回收這種對象。虛擬機
除此以外,還有一種標記類的算法。內存管理
如:根搜索算法,來源於圖的思想,從一個節點對象出發,只要和該對象有關,就依次傳遞,直到將全部節點遍歷完,而剩下的沒有遍歷到的節點,則認爲是可回收的對象,予以回收。io
再如,清除類算法,這類算法有一個典型的特色。將對象記錄在一張表中,仍是從開頭按照引用開始檢索,將全程沒有引用到的對象從表中釋放,在將空間進行壓縮;或將引用到的對象複製到新表,再將原表所有釋放等。這些都是JVM可能採用的方式,具體還看虛擬機對內存對象更深度的管理方式。
·Java的垃圾回收器GC
Java中的垃圾回收器GC總共有三種類型:新生代垃圾回收器,老年代垃圾回收器和通用垃圾回收器。
·1.新生代:Serial、PraNew、Parallel Scavenge
·2.老年代:Serial Old、Parallel Old、CMS
·3.通用:G1
這三種回收器有各自的用途,具體用哪一個看什麼類型的對象。Serial和Serial Old都是單線程;PraNew和CMS擅長多核CPU環境;Parallel系列則追求高併發回收,對CPU利用率較高。
現實中的Java垃圾回收機制
·GC的實質
在這裏直接說GC的實質顯然不太穩當,但仍是要簡單說一下。GC依賴於JVM,是JVM中的一條低優先級的線程——這就意味着即使你使用了諸如:System.gc( ) 或 finalize( ) 這樣的操做,也只是向JVM發起一個回收垃圾的請求,至因而否回收,還看JVM的調度。
·GC的侷限性
GC並無像它所指望的那樣能解決全部的垃圾回收問題。好比:
·1.io類,nio類以及JDBC鏈接中產生的各類對象,沒有顯式的調用 close( ) 方法關閉讀取器、套接字等;
·2.監視器類對象,包括動做監聽器在內的,若是監聽對象已銷亡,但監聽器自己還在,則也容易發生內存泄露;
·3.循環語句中有相似 Object sth = new Object( ) 這樣的語句,在循環中不斷建立新的對象,不斷的放棄以前一次建好的對象,又不斷地進行新的引用,則很容易發生內存泄露.