2019/4/2 星期二
深入研究java gc
引出問題和小結!
應該是全網最全的JVM知識點總結 https://www.toutiao.com/i6717184983829578254/
//此鏈接很重要 推薦收藏
你解釋一下什么是JVM?什么是JDK?什么是JRE?我懵了
https://www.toutiao.com/i6714156440199627276/
小結:
1、為什么使用CMS gc回收算法?
//答:
因為在CMS gc算法執行的6個步驟中,只有在第一步(初始標記(STW Initial Mark))和第四步重新標記階段(STW REMARK)才會暫停整個應用,這樣對應用程序所帶來的影響非常小,缺點是產生內存碎片過多
2、那CMS GC策略如何導致內存碎片過多?
//答:是因為第二步并發標記(concurrent marking)與回收線程會與應用程序爭搶CPU資源,容易產生內存碎片,其二:CMS算法在標記清理之后并沒有重新壓縮分配存活對象,因此整個老生代會產生很多的內存碎片。
3、那為什么CMS gc策略會耗時比較長呢?
//答:
‘stop-the-world’暫停時間也很短暫,耗時較長的(第二步并發標記)標記和(第三步并發預清理)清理都是并發執行的。
內存碎片過多如何觸發Full GC?
//答:
CMS并不是很完美,它會在兩種場景下產生嚴重的Full GC(Concurrent Failure(并發失敗),Promotion Failure (促銷失敗))
具體見:老年代 CMS gc回收算法 對hbase的影響 https://blog.51cto.com/12445535/2373206
HBase在演進的道路上又如何不斷優化CMS GC?
具體內容見下詳細介紹:
題外話:什么是java程序的執行流程;java運行時數據區;java的內存管理 見如下圖:
java程序執行流程:
java運行時數據區:
java的內存管理:
在我們(運行時數據區)之中,內存的分配一共有五塊:
1、堆內存(Heap):保存真正的程序的數據的部分;
2、&&&棧內存(Stack):保存堆內存地址、還保存基本數據、方法的執行;(所有的數據都在棧內存之中)
3、方法區:保存所有方法的具體的操作,該區域屬于共享;
4、程序計數器:這是一塊很小的內存,小到幾乎可以忽略的地步,只是做一個程序執行順序的記錄,只是為了標記我們下一步要執行的代碼的順序號;
5、本地方法棧:該棧之中所保存的都是操作系統的原生函數。
我們關心的主要是堆內存、棧內存、方法區
在整個的JVM內存組成過程之中,(棧內存)是一個非常重要的概念,因為在該內存之中,他需要保存的數據是一組內容,
因為所有的方法在進行遞歸調用的時候都會采用棧的模式。觀察遞歸問題中滿棧的原因取決于服務器內存的大小。
內存操作有關的兩類異常
stackOverFlowError(棧溢出):如果請求的棧的深度過大,虛擬機可能會拋處。
OutOfMemoryError(內存溢出):如果虛擬機的實現中允許、虛擬機棧動態擴展,當內存不足以擴展棧的時候,會拋出。【內存被沾滿,更多情況下表示堆也分配不了了】
實際上上面只是觀察到了兩類可能出現錯誤的代碼,但是并不是意味著棧中只能夠保存一下基本的信息,實際上棧里面保存同樣是一組的數據。
總結:
1、造成stackOverFlowError(棧溢出)OutOfMemoryError(內存溢出)的原因是;
2、在JVM棧內存中保存有棧幁的概念,所有的棧內存采用先進后出的數據結構來進行我們的存儲。
首先需要了解一下什么是java的堆內內存劃分
在實際情況下:java 堆內存劃分分為了(jdk1.8以前和jdk1.8之后)【對于這2者的區別,我們后面介紹】
jvm堆內存劃分(jdk1.8以前):
jvm堆內存劃分(jdk1.8之后):
java堆內存模型
java的垃圾收集主要指的是java堆內存空間,那么在每一次執行GC的時候需要區分出那些堆內存空間需要被回收,那些不應該被回收。 所以為了整個的回收處理方便,JVM將堆內存分為如下的幾個組成部分。而這幾個組成部分你還需要去考慮JDK的版本,現在的JVM內存劃分就必須考慮JDK1.8以前和JDK1.8之后的問題了。
如果簡化點來理解的話:
1、新生代:那些剛剛創建的對象,剛剛創建的對象有可能會存在有許多垃圾對象,那么這些對象應該是被優先回收的;
2、老年代:老不死的那類對象,經過了很多次的清理之后你發現該對象依然有用,
3、永久代:intern()方法進行入池的對象實際上就在永久代中,永久代不會被回收。因為其本身屬于一個bug性的存在(也就是jdk崩潰了,死了永久代CIA能消失),所以在jdk1.8之后,將其更換為元空間(就是電腦的直接內存)。
舉個例子:我電腦有100G內存,80G給了堆內存,那剩下的20G就可以給元空間。
在整個內存的組成過程之中,每一代的內存空間都會有一個伸縮區,那么該區域就可以由JVM根據空間的使用情況,動態擴充。
當我們適當合理的設置了伸縮區的內存大小之后,那么就可以得到良好的性能提升。也就是說最容易的性能提升就是改變伸縮區的內存大小。
首先什么是java gc 、java對象創建流程
java對象創建流程如圖:
1、大多數內存對象要么生存周期比較短,很快就會沒人引用,比如處理RPC請求的buffer可能只會生存幾微秒;
2、要么生存周期比較長,比如Block Cache中的熱點Block,可能就會生存幾分鐘,甚至更長時間。
3、基于這樣的事實,JVM將整個堆內存分為兩個部分:新生代(young generation)和老生代(tenured generation),除此之外,JVM還有一個非堆內存區-Perm區,主要存放class信息以及其他meta元信息,
4、其中Young區又分為Eden區和兩個Survivor 區:S0和S1。
5、一個內存對象在創建之后,首先會為其在新生代申請一塊內存空間,如果這個對象在新生代存活了很長時間,會將其遷移到老生代。
6、在大多數對延遲敏感的業務場景下(比如HBase),建議使用如下JVM參數,-XX:+UseParNewGC和XX:+UseConcMarkSweepGC,其中前者表示對新生代執行并行的垃圾回收機制,而后者表示對老生代執行并行標記-清除垃圾回收機制。
7、可見,JVM允許針對不同內存區執行不同的GC策略。
//在 cdh中默認是這樣設置的
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled
接下來重點先討論一下年輕代
年輕代GC實現復制算法:(年輕代GC策略 – Parallel New Collector)
1、對象初始化之后會被放入Young區,更具體的話應該是Eden區,當Eden區滿了之后,會進行一次GC。
2、GC算法會檢查所有對象的引用情況,如果某個對象還有被引用,表示該對象存活。
3、檢查完成之后,會將這些存活的對象移到S0區,并且回收整個Eden區空間,稱為一次Minor GC;
4、接著新對象進來,又會放入Eden區,滿了之后會檢查S0和Eden區存活的對象,將所有存活的對象移到S1區,再回收整個S0和Eden區空間;
5、很容易理解,S0和S1兩個區總會有一個區是預留給下次存放存活對象用的。
這種算法稱為復制算法,對于這種算法,有兩點需要關注:
提高了解篇
年輕代優化算法
年輕代內存調整參數(重要):
接下來深度研究老年代
什么是老年代 和老年代的full gc:
老生代GC策略 – Concurrent Mark-Sweep(CMS算法)
什么是CMS 為什么CMS?
1、每次執行Minor GC之后,都會有部分生命周期較長的對象被移入老生代,一段時間之后,老生代空間也會被占滿。
2、此時就需要針對老生代空間執行GC操作,此處我們介紹Concurrent Mark-Sweep(CMS)算法。
CMS算法整個流程分為6個階段,其中部分階段會執行 ‘stop-the-world’ 暫停,部分階段會和應用線程一起并發執行:
如圖:
老年代執行CMS過程:
相應的,對于CMS算法,也需要關注兩點:
提高篇
老年代標記清除算法:
老年代標記壓縮算法:
老年代內存調整參數:
永久代調整參數:
元空間調整參數:
可用gc方式小結:
年輕代串行GC(copy)
年輕代并行回收GC
年輕代并行GC
老年代串行GC
老年代并行GC
常用gc策略:
GC調整策略、
收集器參數設置
G1收集器介紹:
參考鏈接:
http://hbasefly.com/2016/05/21/hbase-gc-1/
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
文章題目:深入研究javagc-創新互聯
鏈接地址:http://vcdvsql.cn/article14/iigde.html
成都網站建設公司_創新互聯,為您提供虛擬主機、網站制作、App開發、網站改版、自適應網站、云服務器
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯