JVM-6-GC

引用

  • 狹義引用
    • 地址
  • 擴充引用
    • 強引用 Strong Reference
      • Object obj = new Object()
    • 軟引用 Soft Reference
      • SoftReference稽犁,將要發(fā)生內(nèi)存溢出才會回收
    • 弱引用 Weak Reference
      • WeakReference附较,不影響回收嘹叫,可做回收通知
    • 虛引用 Phantom Reference
      • PhantomReference醇份,不影響回收,可做回收通知

對象判活

  • 引用計數(shù)法
    • 無法解決循環(huán)引用
  • 可達性分析
    • GC Roots
      • 虛擬機棧中引用
      • 類靜態(tài)屬性引用
      • 方法區(qū)常量引用
      • 本地方法棧中JNI引用
    • 對象狀態(tài)
      • GC Roots可達
      • GC Roots不可達但需執(zhí)行finalize
      • 不可達也不需執(zhí)行finalize
    • 執(zhí)行finalize
      • 進入F-Queue姥敛,由虛擬機建立的低優(yōu)先級Finalizer線來執(zhí)行励七,此執(zhí)行表示觸發(fā)崇裁,但不保證執(zhí)行結(jié)束
      • 若finalize方法卡死,會被咔嚓掉
      • finalize方法中可進行一次自救蜻底,但只能救一次
      • finalize方法據(jù)說是在初期對應(yīng)C/C++的析構(gòu)函數(shù)而做的一次折中骄崩,實際并不提倡使用,而用try-finally更好
    • 枚舉根節(jié)點
      • 必須Stop The World薄辅,所以對效率很敏感要拂,全局掃描是不現(xiàn)實的
      • 得益于準確式GC,虛擬機知道某個地址存的是什么類型數(shù)據(jù)站楚,以此建立OopMap(Ordinary Object Pointer)
      • 虛擬機沒有為每條指令都建立OopMap脱惰,因為成本太高
      • 所以有了Safe Point的概念,“可長時間執(zhí)行”的地方窿春,會建立OopMap拉一,即安全點
      • 可長時間執(zhí)行一般指指令序列復(fù)用采盒,即方法調(diào)用,循環(huán)跳轉(zhuǎn)蔚润,異常跳轉(zhuǎn)
      • 有安全點后磅氨,需要考慮怎么讓線程都停在安全點
      • 搶先式中斷(Preemptive Suspension)
        • 發(fā)生GC時虛擬機停止所有線程,恢復(fù)沒有跑到安全點的線程嫡纠,等其安全烦租,幾乎不用
      • 主動式中斷(Voluntary Suspension)
        • 生成一個test輪詢指令,在安全點處執(zhí)行除盏,看是否有中斷標識存在叉橱,若存在就停下自己
        • 具體方案是虛擬機將一個內(nèi)存頁設(shè)為不可讀,test讀取到這里時會產(chǎn)生自陷異常信號者蠕,并在異常處理器中進行線程中斷
      • 安全點的問題
        • 線程處于sleep或者block時赏迟,等線程跑到安全點不現(xiàn)實
      • 安全區(qū)域(Safe Region)
        • 線程進入安全區(qū)域時,就在自己身上打個安全區(qū)域的標簽蠢棱,GC枚舉根節(jié)點時锌杀,就不用管了
        • 當(dāng)線程將要離開安全區(qū)域時,需要檢查系統(tǒng)是否已經(jīng)完成根節(jié)點枚舉或者GC
        • 如果沒有泻仙,就等待直到收到可以離開的信號為止

方法區(qū)回收

  • 虛擬機規(guī)范并未要求方法區(qū)回收
  • 回收對象
    • 廢棄常量
      • 不被引用糕再,會被清出常量池
    • 無用類
      • 該類所有實例已回收
      • 類加載器已被回收
      • Class對象沒有在任何地方被引用
      • 僅僅是可回收,不一定就回收玉转,HotSpot提供了參數(shù)可控制

收集算法

  • 復(fù)制(對新生代分區(qū)后突想,涉及到分配擔(dān)保Handle Promotion,需要老年代做擔(dān)保)
  • 標記-清除(弊端是空間碎片)
  • 標記-整理
  • 實際
    • 分代收集

收集器

  • 搭配關(guān)系
    • 年輕代 - 年老代
      • Serial(Serial Old究抓,CMS)
      • ParNew(Serial Old猾担,CMS)
      • Parallel Scavenge(Serial Old(實際應(yīng)該是PS MarkSweep,只是它和Serial Old的實現(xiàn)太接近了刺下,以至于很多資料中直接以Serial Old來代替)绑嘹,Parallel Old)
    • 年老代 - 年輕代
      • CMS(Serial,ParNew)
      • Serial Old(Serial橘茉,ParNew工腋,Parallel Scavenge)
      • Parallel Old(Parallel Scavenge)
    • G1
  • 說明
    • Parallel Scavenge和G1采用全新代碼框架,其余則共用架構(gòu)
    • 并行:GC多線程畅卓,用戶線程需停止
    • 并發(fā):用戶線程與GC線程同時執(zhí)行擅腰,但可能是交替占用cpu,只是用戶線程不需要暫停
  • 新生代
    • Serial(復(fù)制算法)
      • 用戶多線程-》GC單線程-》用戶多線程
      • 單Cpu下無敵翁潘,甚至2 Cpu下還能虐ParNew
    • ParNew(復(fù)制算法)
      • 用戶多線程-》GC多線程-》用戶多線程
      • 除多線程外趁冈,與Serial基本一致,存在的一個主要原因是只有它能和CMS一起用拜马,而Parallel Scavenge不行
    • Parallel Scavenge(復(fù)制)
      • 和ParNew有相似之處渗勘,不過更關(guān)注于可控的吞吐量
      • MaxGCPauseMillis GC最大停頓時間
      • GCTimeRatio 吞吐量
      • UseAdapativeSizePolicy 自適應(yīng)調(diào)節(jié)新生代大小矾飞,Eden比例,晉升老年代對象年等
  • 老年代
    • Serial Old(標記-整理)
      • 用戶多線程-》GC單線程-》用戶多線程
      • 可作為CMS發(fā)生Concurrent Mode Failure時的備用方案
    • Parallel Old(標記-整理)
      • 用戶多線程-》GC多線程-》用戶多線程
      • 在這個出來前呀邢,由于Parallel Scavenge只能和Serial Old一起使用洒沦,所以實際在吞吐量控制中,效果可能并不如ParNew + CMS
    • CMS(Concurrent Mark Sweep价淌,標記-清除)
      • 用戶多線程-》初始標記單線程-》用戶多線程(并發(fā)標記)-》重新標記多線程-》用戶多線程(并發(fā)清理)-》用戶多線程(重置線程)
      • 主打短停頓
      • 初始標記(Initial Mark)
        • 標記GC Roots能直接關(guān)聯(lián)的對象申眼;單線程
      • 并發(fā)標記(Concurrent Mark)
        • GC Roots Tracing
      • 重新標記(Remark)
        • 修正并發(fā)標記期間的改變,比初始標記稍長蝉衣,遠短于并發(fā)標記括尸;多線程
      • 并發(fā)清除(Concurrent Sweep)
      • 初始標記 + 重新標記
        • Stop The World
    • CMS缺點
      • 并發(fā)GC會消耗cpu,對用戶線程造成影響
        • 為此病毡,曾經(jīng)出現(xiàn)過Incremental Concurrent Mark Sweep濒翻,思想是讓GC和用戶線程交替運行,減少對cpu的占用
        • 效果并不理想啦膜,已經(jīng)被deprecate
      • 無法處理浮動垃圾
        • 浮動垃圾是指在并發(fā)清除階段產(chǎn)生的垃圾有送,本次GC無法清除
      • Concurrent Mode Failure
        • 由于并發(fā)清除階段需要運行用戶線程,所以需要預(yù)留空間
        • 預(yù)留空間太大容易導(dǎo)致GC頻繁
        • 通過-XX:CMSInitiatingOccupancyFraction調(diào)高的話僧家,又可能導(dǎo)致Concurrent Mode Failure
        • 發(fā)生Failure時雀摘,會啟用Serial Old重新進行老年代收集
      • 空間碎片
        • 提供-XX:+UseCMSCompactAtFullCollection 默認開啟
        • -XX:CMSFullGCsBeforeCompaction 默認值0
  • G1
    • 1.7中出現(xiàn),可處理整個堆
    • 標記-整理
      • 用戶多線程-》初始標記單線程-》用戶多線程(并發(fā)標記)-》最終標記多線程-》篩選回收多線程-》用戶多線程
    • 優(yōu)勢
      • 可預(yù)測的停頓八拱,用戶可以控制M毫秒內(nèi)阵赠,GC所用時間不能超過N毫秒
      • 基于Region,即將整個Java堆劃分為若干等大小的Region肌稻,新生代和老年代不再物理隔離清蚀,而都是一部分Region的集合
      • G1跟蹤各個Region垃圾堆積的價值大小(回收所獲得空間大小和回收時間的經(jīng)驗值)爹谭,在后臺維護一個優(yōu)先列表枷邪,每次根據(jù)允許的時間,收集價值最大的Region旦棉,這也是Garbage-First的名稱由來
      • 基于Region有個突出的問題(這個問題在新生代/老年代中也存在齿风,只是沒有這么突出),因為對象引用關(guān)系可能是跨Region的绑洛,如果沒有對應(yīng)措施的話,會導(dǎo)致全堆掃描童本,這是不能容忍的
      • 虛擬機采用的方案是Remembered Set
        • 每個Region都有一個對應(yīng)的Remembered Set
        • 虛擬機發(fā)現(xiàn)應(yīng)用程序在對Reference的數(shù)據(jù)進行寫操作時真屯,會產(chǎn)生一個Write Barrier暫時中斷寫操作
        • 檢查Reference所引用的對象是否在不同的Region
        • 若是,則通過Card Table在被引用對象所屬Region的Remembered Set中記錄該信息
        • 枚舉根節(jié)點時穷娱,掃描Remembered Set以確保掃描不遺漏
    • 步驟(暫不考慮維護Remembered Set的工作)
      • 初始標記(Initial Marking)
      • 并發(fā)標記(Concurrent Marking)
        • 將對象變化記錄在Remembered Set Logs
      • 最終標記(Final Marking)
        • 將Remembered Set Logs合并到Remembered Set中
      • 篩選回收(Live Data Counting and Evacuation)
        • 先對Region的回收價值進行排序绑蔫,然后根據(jù)用戶的期望時間制定回收計劃运沦,這部分其實可以做到并發(fā),只是不并發(fā)的效率更高配深,所以實際實現(xiàn)時并不是并發(fā)

G1和CMS對比

  • 性能對比
    • 軟實時目標(M時間中最大允許GC為N)
      • G1的失敗概率小于CMS携添,并且失敗情況下,G1的超時也小于CMS篓叶;此對比下烈掠,G1完勝
    • 吞吐量對比
      • CMS占優(yōu)勢
  • 共同點:
    • 都立足于低停頓(各種并發(fā)就看出來了)
  • 選擇
    • 在1.7時,建議的還是CMS
    • 不過呢缸托,G1在低停頓已經(jīng)有優(yōu)勢左敌,只是吞吐量還不太好

內(nèi)存分配策略

  • TLAB:Thread Local Allocation Buffer

    • 在線程中劃出緩沖區(qū),用于對象新建
    • 為什么要這個東西呢俐镐,減少分配競爭
  • 對象優(yōu)先在Eden中分配

  • 大對象直接進入老年代矫限,虛擬機提供參數(shù)-XX:PretenureSizeThreshold來控制,大于這個size的對象直接進入老年代佩抹,不過這參數(shù)只對Serial和ParNew有效

  • 長期存活對象進入老年代叼风,為每個對象賦予一個年齡值,達到一定年齡后進入老年代棍苹,可通過參數(shù)-XX:MaxTenuringThreshold來設(shè)置

  • 動態(tài)對象年齡判定咬扇,Survivor中相同年齡所有對象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代廊勃,而無需等到-XX:MaxTenuringThreshold

  • 空間分配擔(dān)保:在發(fā)生Minor GC之前懈贺,虛擬機會先檢查老年代中連續(xù)空間是否大于新生代所有對象空間總和,如果條件成立坡垫,那么可以確保是安全的梭灿;如果不成立,則會查看HandlePromotionFailures設(shè)置值是否允許擔(dān)保失敱啤堡妒;如果允許,那么繼續(xù)檢查老年代可用連續(xù)空間是否大于歷次晉升老年代的平均容量大小溉卓,如果大于皮迟,則嘗試Minor GC;否則桑寨,或者HandlePromotionFailures設(shè)置不允許冒險伏尼,則進行Full GC

  • 不過在JDK6 Update24之后,HandlePromotionFailures已經(jīng)被拋棄了尉尾,新規(guī)則變?yōu)槔夏甏B續(xù)空間大于新生代對象總大小爆阶,或者大于歷次晉升平均大小,就進行Minor GC;否則辨图,進行Full GC

  • 擔(dān)保失敗時班套,會重新觸發(fā)Full GC;雖然這比直接Full GC代價要大故河,但是從總體減少Full GC頻率上吱韭,還是很有效的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鱼的,隨后出現(xiàn)的幾起案子理盆,更是在濱河造成了極大的恐慌,老刑警劉巖鸳吸,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熏挎,死亡現(xiàn)場離奇詭異,居然都是意外死亡晌砾,警方通過查閱死者的電腦和手機坎拐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來养匈,“玉大人哼勇,你說我怎么就攤上這事∨缓酰” “怎么了积担?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長猬仁。 經(jīng)常有香客問我帝璧,道長,這世上最難降的妖魔是什么湿刽? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任的烁,我火速辦了婚禮,結(jié)果婚禮上诈闺,老公的妹妹穿的比我還像新娘渴庆。我一直安慰自己,他們只是感情好雅镊,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布襟雷。 她就那樣靜靜地躺著,像睡著了一般仁烹。 火紅的嫁衣襯著肌膚如雪耸弄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天晃危,我揣著相機與錄音叙赚,去河邊找鬼老客。 笑死僚饭,一個胖子當(dāng)著我的面吹牛震叮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鳍鸵,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼苇瓣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了偿乖?” 一聲冷哼從身側(cè)響起击罪,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贪薪,沒想到半個月后媳禁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡画切,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年竣稽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霍弹。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡毫别,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出典格,到底是詐尸還是另有隱情岛宦,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布耍缴,位于F島的核電站砾肺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏防嗡。R本人自食惡果不足惜变汪,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望本鸣。 院中可真熱鬧疫衩,春花似錦、人聲如沸荣德。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涮瞻。三九已至鲤拿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間署咽,已是汗流浹背近顷。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工生音, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窒升。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓缀遍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饱须。 傳聞我的和親對象是個殘疾皇子域醇,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 原文閱讀 前言 這段時間懈怠了,罪過蓉媳! 最近看到有同事也開始用上了微信公眾號寫博客了譬挚,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 5,952評論 2 31
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理酪呻,因此不免有一些不準確的地方减宣,同時不同JDK版本的...
    高廣超閱讀 15,565評論 3 83
  • 0. 前言 JVM筆記系列,以JDK1.7為基準玩荠,主要以《深入理解Java虛擬機》(第二版)和《Java虛擬機規(guī)范...
    郭尋撫閱讀 897評論 0 3
  • http://www.cnblogs.com/angeldevil/p/3801189.html值得一看 Clas...
    snail_knight閱讀 1,418評論 1 0
  • JVM架構(gòu) 當(dāng)一個程序啟動之前漆腌,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,650評論 0 7