java回收算法_深入理解java垃圾回收算法

轉自:http://www.cnblogs.com/huajiezh/p/5769255.html

Java虛擬機的內存區域中,程序計數器、虛擬機棧和本地方法棧三個區域是線程私有的,隨線程生而生,隨線程滅而滅;棧中的棧幀隨着方法的進入和退出而進行入棧和出棧操作,每個棧幀中分配多少內存基本上是在類結構確定下來時就已知的,因此這三個區域的內存分配和回收都具有確定性。垃圾回收重點關注的是堆和方法區部分的內存。

常用的垃圾回收算法有:

(1).引用計數算法:

給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器都為0的對象就是不再被使用的,垃圾收集器將回收該對象使用的內存。

引用計數算法實現簡單,效率很高,微軟的COM技術、ActionScript、Python等都使用了引用計數算法進行內存管理,但是引用計數算法對於對象之間相互循環引用問題難以解決,因此java並沒有使用引用計數算法。

(2).根搜索算法:

通過一系列的名為“GC Root”的對象作為起點,從這些節點向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當一個對象到GC Root沒有任何引用鏈相連時,則該對象不可達,該對象是不可使用的,垃圾收集器將回收其所占的內存。

主流的商用程序語言C#、java和Lisp都使用根搜素算法進行內存管理。

在java語言中,可作為GC Root的對象包括以下幾種對象:

a. java虛擬機棧(棧幀中的本地變量表)中的引用的對象。

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

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

d.本地方法棧中JNI本地方法的引用對象。

java方法區在Sun HotSpot虛擬機中被稱為永久代,很多人認為該部分的內存是不用回收的,java虛擬機規范也沒有對該部分內存的垃圾收集做規定,但是方法區中的廢棄常量和無用的類還是需要回收以保證永久代不會發生內存溢出。

判斷廢棄常量的方法:如果常量池中的某個常量沒有被任何引用所引用,則該常量是廢棄常量。

判斷無用的類:

(1).該類的所有實例都已經被回收,即java堆中不存在該類的實例對象。

(2).加載該類的類加載器已經被回收。

(3).該類所對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射機制訪問該類的方法。

Java中常用的垃圾收集算法:

(1).標記-清除算法:

最基礎的垃圾收集算法,算法分為“標記”和“清除”兩個階段:首先標記出所有需要回收的對象,在標記完成之后統一回收掉所有被標記的對象。

標記-清除算法的缺點有兩個:首先,效率問題,標記和清除效率都不高。其次,標記清除之后會產生大量的不連續的內存碎片,空間碎片太多會導致當程序需要為較大對象分配內存時無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作。

(2).復制算法:

將可用內存按容量分成大小相等的兩塊,每次只使用其中一塊,當這塊內存使用完了,就將還存活的對象復制到另一塊內存上去,然后把使用過的內存空間一次清理掉。這樣使得每次都是對其中一塊內存進行回收,內存分配時不用考慮內存碎片等復雜情況,只需要移動堆頂指針,按順序分配內存即可,實現簡單,運行高效。

復制算法的缺點顯而易見,可使用的內存降為原來一半。

(3).標記-整理算法:

標記-整理算法在標記-清除算法基礎上做了改進,標記階段是相同的標記出所有需要回收的對象,在標記完成之后不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,在移動過程中清理掉可回收的對象,這個過程叫做整理。

標記-整理算法相比標記-清除算法的優點是內存被整理以后不會產生大量不連續內存碎片問題。

復制算法在對象存活率高的情況下就要執行較多的復制操作,效率將會變低,而在對象存活率高的情況下使用標記-整理算法效率會大大提高。

(4).分代收集算法:

根據內存中對象的存活周期不同,將內存划分為幾塊,java的虛擬機中一般把內存划分為新生代和年老代,當新創建對象時一般在新生代中分配內存空間,當新生代垃圾收集器回收幾次之后仍然存活的對象會被移動到年老代內存中,當大對象在新生代中無法找到足夠的連續內存時也直接在年老代中創建。

現在的Java虛擬機就聯合使用了分代復制、標記-清除和標記-整理算法,java虛擬機垃圾收集器關注的內存結構如下:

1a669aacb93f409dd88450478b4313eb.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值