Java內存回收(垃圾回收)機制總結

一、背景:

Java程序員編寫程序時,對於新建的對象,當不再需要此對象時,不必去釋放這個對象所佔用的空間,這個工作是由Java虛擬機自己完成的 ,即內存回收或垃圾回收。

二、如何知道一個對象所佔用的空間可以回收了呢?

1.常用的一種算法是引用計數法,如果一個對象的引用爲0了,那就可以回收了。但是對於這種方法致命缺陷,當對象之間存在循環引用的時候,A引用B,B引用A,這樣A和B的引用就一直不會爲0,那就無法回收了。

2、Java採用的算法爲根搜索算法,以一系列GC Roots爲起點,向下搜索,如果存在引用,則對象依然在用,不能回收;如果不存在引用,則可以回收。

可以作爲GC Roots的有如下幾種:

a、虛擬機棧(棧幀中的本地變量表)中的引用的對象
b、方法區中的類靜態屬性引用的對象
c、方法區中的常量引用的對象
d、本地方法棧中JNI的引用的對象

三、java堆棧內存結構劃分:

1.新生代(Young Generation):又細分爲三塊(eden,S0,S1)

 新的對象總是在新生代創建。

2.老年代(Old Generation)

 在新生代存放一定時間之後,在新生代空間不夠時,對象會被移到老年代。

3.永久代(Permanent)

用於存在類信息。對於動態生成的類,後續不會再使用到,所以可以進行回收。

四、爲什麼採用分代(區)的方式來進行堆棧空間的管理呢?

因爲不同的對象存活時間不同,多數對象存活時間很短,少數對象存活時間很長。如果每次回收都遍歷所有對象,效率將會非常低。按對象存活時間長短,劃分不同的內存區域來管理對象,對不同的區採用不同的回收算法。

五、主要的空間回收算法:

1.複製算法

對於新生代,劃分了eden/S0/S1三塊區域,開始對象創建在eden區域上。

下面來描述一下可能的操作過程,各個java虛擬機的實現會有差異,下面是大致進行闡述。

第一次清理的時候,將可以清除的對象刪除,將要保留的對象都複製到S0區域,eden區域清空,對象年齡標記增長1;

第二次清理的時候,將可以清除的對象刪除,將要保留的對象從eden和S0都複製到S1,並將eden和S0都清空,對象年齡標記增長1;

第三次清理的時候,將可以清除的對象刪除,將要保留的對象從eden和S1都複製到S0,並將eden和S1都清空,對象年齡標記增長1;

後續清理的時候,以此重複上面的步驟,當對象的年齡達到一定值時,就被移到老年代中去。

對於上面的過程,可以通過jvisualvm觀測到,會發現eden和S0同時被清空,對象轉移到S1,或eden和S1同時被清空,對象轉移到S0.

下面給出兩張jvisualvm的截圖:

時刻1:

時刻2:

時刻3:

通過上面三張圖對比可以看到,當S0被佔用時,S1就是空的;S1被佔用時,S0就是空的,這也就印證了上面算法描述裏說的信息。

2.標記清除算法(包括整理)

因爲老年代中,可以回收的對象很少,所以觸發對老年代的回收機率也比較低,對於老年代也不採用複製算法,因爲那樣空間利用率比較低,而是採用標記清除(整理)方式。如果對應對象的空間可以回收了,就進行回收,並對對象存儲位置進行移動,將對象移到到一起,避免中間存在空隙,便於後續內存分配。

六、幾個可以用於指定java虛擬機各個塊大小的參數:

-XX:PermSize       設置永久代初始大小(樣例:-XX:PermSize=40M)
-XX:MaxPermSize    設置永久代最大大小(樣例:-XX:MaxPermSize=100M)
(注:java對此參數值限制,具體限制可能因操作系統、CPU/內存差異而又不同,在Window7上測試時,最小值爲12M;不能設置爲奇數,必須爲偶數)

-XX:NewSize        設置新生代初始大小(樣例:-XX:NewSize=10M)
-XX:MaxNewSize     設置新生代最大值(樣例:-XX:MaxNewSize=20M)
-XX:SurvivorRatio  設置新生代中eden和survivor區(S0/S1)的比例,通過驗證,實際大小比例爲該值*1.2,如設置爲8,則eden空間大小/S0=8*1.2(樣例:-XX:SurvivorRatio=8)
-Xmx               設置堆棧最大值,包括老年代和新生代,不包括永久代(樣例-Xmx100M)
-Xms               設置堆棧初始大小(樣例:-Xms50M)
-XX:NewRatio       老年代和新生代的大小比例,設置此參數時不能設置MaxNewSize,否則此參數失效(樣例:-XX:NewRatio=2)


參考資料:

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

http://www.open-open.com/lib/view/open1380593930103.html

http://blog.csdn.net/time_hunter/article/details/12405127



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章