JVM垃圾回收机制学习
一、可回收對象判定方法
識別方式有兩種。一是,引用計數算法;二是,可達性分析。
第一種方法:引用計數算法。當一個對象被引用時,引用計數器加1,當引用失效時,引用計數器減1。當一個對象的引用次數為0時,表示這個對象是可以被回收的。這種方法的優點是快和簡單,只要將所有對象遍歷一遍便可,缺點是:如果對象之間存在循環引用,則無法回收。比如:對象A引用了B,B中也引用了A,如果除此之外沒有任何對象引用了A和B,很顯然AB是應該被回收的,但是此時兩者的引用次數是1,這時,JVM無法對AB進行回收。
第二種方法:可達性分析。通過一系列被稱為“gc roots”的對象作為起點,從這些節點開始向下進行搜索,搜索所走過的路徑成為引用鏈。當一個對象到“gc roots”之間沒有任何引用鏈相連時,則該對象是不可達的,也就是可以回收的。這種方式可以解決循環調用的問題,JVM中使用的是這種判定方法。
二、垃圾回收算法
垃圾回收算法有以下四種:
標記-清除算法;
復制算法;
標記-整理算法;
分代收集算法;
標記-清除算法分為“標記”和“清除”兩個階段,“標記”階段將需要回收的對象標記出來,“清除”階段回收被標記的對象。這是一種最基本的垃圾回收算法,后面很多種垃圾回收算法都是基于這種算法的不足改進而得到的。這種回收方法的缺點是回收之后會產生大量內存碎片,因為回收過程只是簡單的釋放掉被標記對象。內存碎片太多的話,當我們需要分配大內存對象時,無法找到連續的內存空間,以致分配內存失敗。
復制算法將內存分成兩半,一半使用(在用內存),一半不用(未用內存)。標記過程同上,只是在回收時,把在用內存中的未標記對象復制到未用內存中,然后把在用內存統一全部回收。這種方法不會產生內存碎片,但是相當于把內存容量減少了一半。在實際算法中,在用內存和未用內存往往不是對半分的,因為如果每次清理的時候,大部分對象都死了,只有少部分存活(實際上,下面的分代收集算法中的新生代就符合這樣的特點),那么,未用內存只要很小就可以了。
標記-整理算法也是由標記-清除算法發展而來,只是“清除”之后,會把內存整理一遍,這樣就沒有碎片了。但是,這種算法要考慮一致性問題,就是整理的過程中,標記不能變動,這就相當于虛擬機要暫停,等待內存整理完畢再運行,而整理過程還是挺耗時的。但是,如果對象存活的時間很長,存活率很高,每次清理都只有少部分對象死亡(實際上,下面的分代收集算法中的老生代就符合這樣的特點),那么,這種算法消耗的時間會大大減少。
分代收集算法,這是聽得最多的一種算法了,就是將對象分為新生代和老生代,新生代對象的特點是存活時間短,存活率低,老生代剛好相反。根據新生代和老生代的特點,對新生代使用復制算法,對老生代使用標記整理算法。
總結
以上是生活随笔為你收集整理的JVM垃圾回收机制学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Model、ModelMap和Model
- 下一篇: 层级分类(续)-使用B-CNN(Bran