3.1.2 JVM性能調(diào)優(yōu)-垃圾回收機(jī)制

什么是垃圾回收機(jī)制

C/C++語言 是手動來回收堆內(nèi)存里不再使用的對象,而JAVA則是由JVM來自動回收

如何確定內(nèi)存需要被回收了

標(biāo)記 ,標(biāo)記正在使用的內(nèi)存,不在使用的內(nèi)存,其中有2種內(nèi)存

  • 對象內(nèi)存回收,即堆內(nèi)存的回收,使用可達(dá)性分析算法來回收
  • 方法區(qū)回收 這一節(jié)沒有細(xì)說

可達(dá)性算法

可達(dá)性算法有一個根GCRoots,然后將所有相關(guān)的對象與它相連,如果某個對象在某個時候不可達(dá)到GCroots,那么它就可以被回收

具體的算法實(shí)現(xiàn)

所有的都是基于標(biāo)記--清除這一算法的,然后有2種改進(jìn)型

  1. 標(biāo)記-清除 優(yōu)點(diǎn):快 缺點(diǎn):有內(nèi)存碎片問題(就是內(nèi)存雖然還有很多空間,但卻不連續(xù),實(shí)際上是不能存儲數(shù)據(jù)的)
  2. 標(biāo)記-復(fù)制-清除: 優(yōu)點(diǎn):解決了碎片問題 缺點(diǎn):占用空間
  3. 標(biāo)記-清除-整理 在1的基礎(chǔ)上,將內(nèi)存整理成連續(xù)的 缺點(diǎn):慢

具體的JVM實(shí)現(xiàn)

可以看到以上三種方法各有利弊,所以JVM實(shí)現(xiàn)的時候,在不同的場景使用不同的方法

分代收集

JVM大多數(shù)會使用分帶收集實(shí)現(xiàn),即新生代-次新生代-次次新生代--老生代
大概的算法就是

  1. 新建的對象放在新生代,使用標(biāo)記-清除 這種方法,速度快
  2. 經(jīng)歷一次GC的,給它累加一個計(jì)數(shù)器,然后放到次新生代
  3. 當(dāng)一個對象經(jīng)歷了數(shù)次GC,計(jì)數(shù)器累加到一定的次數(shù)時,JVM認(rèn)為他經(jīng)常使用,所以放到老生代,老生代使用標(biāo)記-清除-整理的方法
  4. 空間大的對象也會直接放到老生代
    經(jīng)歷多少次放到老生代,多大的對象會放到老生代,這些都是可以用參數(shù)來設(shè)置的

收集器

并行收集器

跟串行收集器的區(qū)別就是新生代GC和老生代GC一起進(jìn)行,可以設(shè)置GC時間和吞吐量等值,可以自動進(jìn)行適應(yīng)性調(diào)整Eden,Surviror大小和MaxTenuringThreshold大小,感覺可以簡單理解成多線程了

吞吐量 用戶代碼運(yùn)行時間/(用戶代碼運(yùn)行時間+GC時間)
可以設(shè)置的參數(shù)
  • -XX:ParallelGCThreads 設(shè)置用于垃圾回收的線程數(shù)。通常情況下可以和CPU數(shù)量相等
  • -XX:MaxGCPauseMills 設(shè)置最大垃圾收集停頓時間。它是一個大于0 的證書
  • -XX:GCTimeRatio 設(shè)置吞吐量大小,它是一個0-100之間的整數(shù)
  • -XX:UseAdaptiveSizePolicy: 打開自使用GC策略,達(dá)到在對大小、吞吐量和停頓時間之間的平衡

ParallelScavenge和Parallel Old

服務(wù)器模式默認(rèn)使用這個并發(fā)收集器,它有年輕代和老年代兩個實(shí)現(xiàn)

并行收集器G1

JDK1.9后默認(rèn)的收集器,不區(qū)分年輕代和老年代的實(shí)現(xiàn)


截屏2019-12-07下午5.36.28.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容