JVM G1详解
java程序性能
當我們調優java程序時,通常的目標有兩個:
響應能力 或者 吞吐量
響應能力
響應能力指一個程序或者系統對請求的是否能夠及時響應。
比如:
一個桌面UI能多快的響應一個事件;
一個網站能夠多快返回一個頁面請求;
數據庫能夠多快返回查詢的數據;
對于這類對響應能力敏感的場景,長時間的停頓是無法接受的。
吞吐量
吞吐量關注的是,在一個指定的時間內,最大化一個應用的工作量。
如下方式來衡量一個系統吞吐量的好壞:
在一小時內同一個事務(或者任務、請求)完成的次數(tps)。
數據庫一小時可以完成多少次查詢;
對于關注吞吐量的系統,卡頓是可以接受的,因為這個系統關注長時間的大量任務的執行能力,單次快速的響應并不值得考慮。
應用程序運行實際/實際時間(開始時間戳-結束時間戳)
understanding TPS
G1 Garbage Collector
G1垃圾收集器
g1收集器是一個面向服務端的垃圾收收集器,適用于多核處理器、大內存容量的服務端系統。
它滿足短時間gc 停頓的同時達到一個高的吞吐量。JDK7以上版本適用。
g1收集器的設計目標:
與應用線程同時工作,幾乎不需要stop-the-world(與CMS類似);
整理剩余空間,不產生內存碎片;(CMS只能在full-GC時,用stop-the-world整理碎片內存)
GC停頓更加可控;
不犧牲系統的吞吐量;
gc不要求額外的內存空間(CMS需要預留空間存儲浮動垃圾);
G1的設計規劃,是要替換掉CMS。
G1在某些方便彌補了CMS的不足,比如,CMS使用的是mark-sweep算法,自然會產生內存碎片;然而G1基于copying算法,高效的整理剩余內存,而不需要使用free-list去管理內存碎片。
另外,G1提供了更多手段,以達到對gc停頓時間可控。
之前的GC收集器對Heap的劃分:
G1對Heap的劃分:
heap被劃分為一個個相等的不連續的內存區域(regions),每個region都有一個分代的角色:eden、survivor、old(old還有一種細分 humongous,用來存放大小超過 region 50%以上的巨型對象)。
但是對每個角色的數量并沒有強制的限定,也就是說對每種分代內存的大小,可以動態變化(默認年輕代占整個heap的5%)。
G1最大的特點就是高效的執行回收,優先去執行那些大量對象可回收的區域(region)。
另外,G1使用了gc停頓可預測的模型,來滿足用戶設定的gc停頓時間,根據用戶設定的目標時間,g1會自動的選擇哪些region要清楚,一次清除多少個region。
G1從多個region中復制存活的對象,然后集中放入一個region中,同時整理、清除內存(copying收集算法)。
注意對比之前的垃圾收集器(主要是CMS):
對比使用mark-sweep的CMS,g1使用的copying算法不會造成內存碎片;
對比ParallelScavenge(基于copying )、ParallelOld收集器(基于mark-compact-sweep),Parallel
會對整個區域做整理導致gc Pause會比較長,而g1只是特定的整理幾個region。
值得注意:g1不是一個實時的收集器,與parallelScavenge一樣,對gc 停頓時間的設置并不絕對生效,只是g1有較高的幾率保證不超過設定gc停頓時間。與之前的gc收集器對比,g1會根據用戶設定的gc停頓時間,智能評估一下哪幾個region需要被回收可以滿足用戶設定。
G1內存的分配
1.TLAB(TLAB占用年輕代內存). 默認使用TLAB加速內存分配,之前文章已經講過,不贅述。
2.Eden.如果TLAB不夠用,則在Eden中分配內存生成對象。
3.Humongous.如果對象需要的內存超過一個region的50%以上,會忽略前兩個步驟直接在老年代的humongous中分配(連續的Region)。
何時使用G1(-XX:+UseG1GC)
1.大內存中為了達到低gc延遲.
比如:heap size >=6G,gc pause <=0.5s
2.FullGC時間太長,或者太頻繁。
調優參數:
-XX:MaxGCPauseMillis=200
用戶設定的最大gc 停頓時間,默認是200ms.
-XX:InitiatingHeapOccupancyPercent=45
默認是45,也就是heap中45%的容量被使用,則會觸發concurrent gc。
G1垃圾回收步驟詳解
G1提供了兩種GC模式,Young GC和Mixed GC,兩種都是Stop The World(STW)的
G1 Young GC(STW)
1.當eden數據滿了,則觸發g1 YGC
2.并行的執行:
YGC 將 eden region 中存活的對象拷貝到survivor,或者直接晉升到Old Region中;將Survivor Regin中存活的對象拷貝到新的Survivor或者晉升old region。
3.計算下一次YGC eden、Survivor的尺寸
G1 Mix GC
在G1 GC中,它主要是為Mixed GC提供標記服務的,并不是一次GC過程的一個必須環節。global concurrent marking的執行過程分為五個步驟:
初始標記(initial mark,STW)
在此階段,G1 GC 對根進行標記。該階段與常規的 (STW) 年輕代垃圾回收密切相關。
根區域掃描(root region scan)
G1 GC 在初始標記的存活區掃描對老年代的引用,并標記被引用的對象。該階段與應用程序(非 STW)同時運行,并且只有完成該階段后,才能開始下一次 STW 年輕代垃圾回收。
并發標記(Concurrent Marking)
G1 GC 在整個堆中查找可訪問的(存活的)對象。該階段與應用程序同時運行,可以被 STW 年輕代垃圾回收中斷
最終標記(Remark,STW)
該階段是 STW 回收,幫助完成標記周期。G1 GC 清空 SATB 緩沖區,跟蹤未被訪問的存活對象,并執行引用處理。
清除垃圾(Cleanup,STW)
在這個最后階段,G1 GC 執行統計和 RSet 凈化的 STW 操作。在統計期間,G1 GC 會識別完全空閑的區域和可供進行混合垃圾回收的區域。清理階段在將空白區域重置并返回到空閑列表時為部分并發。
一、G1收集器簡介
G1收集器(JDK1.7u4正式出現)
普遍存在:全內存掃描問題。
傳統的收集器不能滿足高內存高cpu的要求,這才是G1產生的原因。
2.G1區域劃分
在G1之中不再區分所謂的年輕代、老年代內存空間,所有的內存空間就是一塊。但是要劃分出不同的子區域。
二、G1收集策略
雖然在G1收集器里面將整個內存區域都混合在了一起,但是其本身依然也是在小范圍內要進行年輕代與老年代的區分,也就是說依然會采用不同的GC方式來處理不同的區域。
G1——年輕代有對象
G1——年輕代對象被回收
所有的垃圾內存的保存區域有可能會被清空后重新分配。
但是老年代的處理流程不一樣了,因為任何時候如果要想標注老年代的不用內存空間,都需要進行一些暫停,而G1之中的最大好處它不用進行全內存掃描,只需要按照區域來進行掃描即可。
G1老年代回收
G1——老年代,標記階段
G1——老年代,根區域掃描
G1——老年代,重新標記階段
G1——老年代,清理、拷貝階段
G1——清理完畢
三、G1相關處理參數
清楚了G1的基本運行原理之后,那么下面就需要進行一些G1的配置。(需慎重使用,可能會有一些問題出現)
G1收集器參數
范例:使用G1回收器
java -Xmx10m -Xms10m -XX:+UseG1GC -XX:+PrintGCDetails TestDemo
1
G1處理和傳統的垃圾收集策略是不同的,關鍵的因素是它將所有的內存進行了子區域的劃分。
g1 對老年代回收-總結:
1.并發標記階段(Concurrent Marking Phase):
在不產生stop-the-world,與程序進程并發的情況下,活躍度(可達性分析)被分析出來。
活躍度越低,代表回收的效率越高,越值得優先回收。
2.復制、清理階段(Copying/Cleanup Phase)
年輕代、老年代在這個階段同時被回收掉。老年代被回收的region,是根據這個region的存活度來選擇的。
正因為當初對未來做了太多的憧憬,所以對現在的自己尤其失望。生命中曾經有過的所有燦爛,終究都需要用寂寞來償還。
總結
- 上一篇: 列出一个买东西的好网站,值得推荐
- 下一篇: 台式电脑怎么链接路由器台式机如何连到路由