<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          7 種 JVM 垃圾回收器,你知道幾個?

          共 4380字,需瀏覽 9分鐘

           ·

          2020-09-05 01:14

          前言

          今天我們來講講jvm最重要的堆內(nèi)存是如何使用垃圾回收器進行垃圾回收,并且如何使用命令去配置使用這些垃圾回收器。

          堆內(nèi)存詳解

          上面這個圖大家應(yīng)該已經(jīng)很明白了吧。大家就可以理解成一個房子被分成了幾個房間,每個房間的作用不同而已,有的是嬰兒住的,有的是父母住的,有的是爺爺奶奶住的

          • 堆內(nèi)存被劃分為兩塊,一塊的年輕代,另一塊是老年代。

          • 年輕代又分為Edensurvivor。他倆空間大小比例默認為8:2,

          • 幸存區(qū)又分為s0s1。這兩個空間大小是一模一樣的,就是一對雙胞胎,他倆是1:1的比例

          堆內(nèi)存垃圾回收過程

          第一步

          新生成的對象首先放到Eden區(qū),當Eden區(qū)滿了會觸發(fā)Minor GC。

          第二步

          第一步GC活下來的對象,會被移動到survivor區(qū)中的S0區(qū),S0區(qū)滿了之后會觸發(fā)Minor GC,S0區(qū)存活下來的對象會被移動到S1區(qū),S0區(qū)空閑。

          S1滿了之后在GC,存活下來的再次移動到S0區(qū),S1區(qū)空閑,這樣反反復(fù)復(fù)GC,每GC一次,對象的年齡就漲一歲,達到某個值后(15),就會進入老年代

          第三步

          在發(fā)生一次Minor GC后(前提條件),老年代可能會出現(xiàn)Major GC,這個視垃圾回收器而定。

          Full GC觸發(fā)條件

          • 手動調(diào)用System.gc,會不斷的執(zhí)行Full GC

          • 老年代空間不足/滿了

          • 方法區(qū)空間不足/滿了

          注意

          們需要記住一個單詞:stop-the-world。它會在任何一種GC算法中發(fā)生。stop-the-world 意味著JVM因為需要執(zhí)行GC而停止應(yīng)用程序的執(zhí)行。

          當stop-the-world 發(fā)生時,除GC所需的線程外,所有的線程都進入等待狀態(tài),直到GC任務(wù)完成。GC優(yōu)化很多時候就是減少stop-the-world 的發(fā)生。

          回收哪些區(qū)域的對象

          需要注意的是,JVM GC只回收堆內(nèi)存方法區(qū)內(nèi)的對象。而棧內(nèi)存的數(shù)據(jù),在超出作用域后會被JVM自動釋放掉,所以其不在JVM GC的管理范圍內(nèi)。

          堆內(nèi)存常見參數(shù)配置

          參數(shù)描述
          -Xms堆內(nèi)存初始大小,單位m、g
          -Xmx堆內(nèi)存最大允許大小,一般不要大于物理內(nèi)存的80%
          -XX:PermSize非堆內(nèi)存初始大小,一般應(yīng)用設(shè)置初始化200m,最大1024m就夠了
          -XX:MaxPermSize非堆內(nèi)存最大允許大小
          -XX:NewSize(-Xns)年輕代內(nèi)存初始大小
          -XX:MaxNewSize(-Xmn)年輕代內(nèi)存最大允許大小
          -XX:SurvivorRatio=8年輕代中Eden區(qū)與Survivor區(qū)的容量比例值,默認為8,即8:1
          -Xss堆棧內(nèi)存大小
          -XX:NewRatio=老年代/新生代設(shè)置老年代和新生代的大小比例
          -XX:+PrintGCjvm啟動后,只要遇到GC就會打印日志
          -XX:+PrintGCDetails查看GC詳細信息,包括各個區(qū)的情況
          -XX:MaxDirectMemorySize在NIO中可以直接訪問「直接內(nèi)存」,這個就是設(shè)置它的大小,不設(shè)置默認就是最大堆空間的值-Xmx
          -XX:+DisableExplicitGC關(guān)閉System.gc()
          -XX:MaxTenuringThreshold垃圾可以進入老年代的年齡
          -Xnoclassgc禁用垃圾回收
          -XX:TLABWasteTargetPercentTLAB占eden區(qū)的百分比,默認是1%
          -XX:+CollectGen0FirstFullGC時是否先YGC,默認false

          TLAB 內(nèi)存

          TLAB全稱是Thread Local Allocation Buffer即線程本地分配緩存,從名字上看是一個線程專用的內(nèi)存分配區(qū)域,是為了加速對象分配而生的。

          每一個線程都會產(chǎn)生一個TLAB,該線程獨享的工作區(qū)域,java虛擬機使用這種TLAB區(qū)來避免多線程沖突問題,提高了對象分配的效率。

          TLAB空間一般不會太大,當大對象無法在TLAB分配時,則會直接分配到堆上。

          參數(shù)描述
          -Xx:+UseTLAB使用TLAB
          -XX:+TLABSize設(shè)置TLAB大小
          -XX:TLABRefillWasteFraction設(shè)置維護進入TLAB空間的單個對象大小,他是一個比例值,默認為64,即如果對象大于整個空間的1/64,則在堆創(chuàng)建
          -XX:+PrintTLAB查看TLAB信息
          -Xx:ResizeTLAB自調(diào)整TLABRefillWasteFraction閥值。

          垃圾回收器總覽

          新生代可配置的回收器:Serial、ParNew、Parallel Scavenge

          老年代配置的回收器:CMS、Serial Old、Parallel Old

          新生代和老年代區(qū)域的回收器之間進行連線,說明他們之間可以搭配使用。

          新生代垃圾回收器

          Serial 垃圾回收器

          Serial收集器是最基本的、發(fā)展歷史最悠久的收集器。俗稱為:串行回收器,采用復(fù)制算法進行垃圾回收

          特點

          串行回收器是指使用單線程進行垃圾回收的回收器。每次回收時,串行回收器只有一個工作線程。

          對于并行能力較弱的單CPU計算機來說,串行回收器的專注性和獨占性往往有更好的性能表現(xiàn)。

          它存在Stop The World問題,及垃圾回收時,要停止程序的運行。

          使用-XX:+UseSerialGC參數(shù)可以設(shè)置新生代使用這個串行回收器

          ParNew 垃圾回收器

          ParNew其實就是Serial的多線程版本,除了使用多線程之外,其余參數(shù)和Serial一模一樣。俗稱:并行垃圾回收器,采用復(fù)制算法進行垃圾回收

          特點

          ParNew默認開啟的線程數(shù)與CPU數(shù)量相同,在CPU核數(shù)很多的機器上,可以通過參數(shù)-XX:ParallelGCThreads來設(shè)置線程數(shù)。

          它是目前新生代首選的垃圾回收器,因為除了ParNew之外,它是唯一一個能與老年代CMS配合工作的。

          它同樣存在Stop The World問題

          使用-XX:+UseParNewGC參數(shù)可以設(shè)置新生代使用這個并行回收器

          ParallelGC 回收器

          ParallelGC使用復(fù)制算法回收垃圾,也是多線程的。

          特點

          就是非常關(guān)注系統(tǒng)的吞吐量,吞吐量=代碼運行時間/(代碼運行時間+垃圾收集時間)

          -XX:MaxGCPauseMillis:設(shè)置最大垃圾收集停頓時間,可用把虛擬機在GC停頓的時間控制在MaxGCPauseMillis范圍內(nèi),如果希望減少GC停頓時間可以將MaxGCPauseMillis設(shè)置的很小,但是會導(dǎo)致GC頻繁,從而增加了GC的總時間,降低吞吐量。所以需要根據(jù)實際情況設(shè)置該值。

          -Xx:GCTimeRatio:設(shè)置吞吐量大小,它是一個0到100之間的整數(shù),默認情況下他的取值是99,那么系統(tǒng)將花費不超過1/(1+n)的時間用于垃圾回收,也就是1/(1+99)=1%的時間。

          另外還可以指定-XX:+UseAdaptiveSizePolicy打開自適應(yīng)模式,在這種模式下,新生代的大小、eden、from/to的比例,以及晉升老年代的對象年齡參數(shù)會被自動調(diào)整,以達到在堆大小、吞吐量和停頓時間之間的平衡點。

          使用-XX:+UseParallelGC參數(shù)可以設(shè)置新生代使用這個并行回收器

          老年代垃圾回收器

          SerialOld 垃圾回收器

          SerialOld是Serial回收器的老年代回收器版本,它同樣是一個單線程回收器。

          用途

          • 一個是在JDK1.5及之前的版本中與Parallel Scavenge收集器搭配使用,

          • 另一個就是作為CMS收集器的后備預(yù)案,如果CMS出現(xiàn)Concurrent Mode Failure,則SerialOld將作為后備收集器。

          使用算法:標記 - 整理算法

          ParallelOldGC 回收器

          老年代ParallelOldGC回收器也是一種多線程的回收器,和新生代的ParallelGC回收器一樣,也是一種關(guān)注吞吐量的回收器,他使用了標記壓縮算法進行實現(xiàn)。

          -XX:+UseParallelOldGc進行設(shè)置老年代使用該回收器

          -XX:+ParallelGCThreads也可以設(shè)置垃圾收集時的線程數(shù)量。

          CMS 回收器

          CMS全稱為:Concurrent Mark Sweep意為并發(fā)標記清除,他使用的是標記清除法。主要關(guān)注系統(tǒng)停頓時間。

          使用-XX:+UseConcMarkSweepGC進行設(shè)置老年代使用該回收器。

          使用-XX:ConcGCThreads設(shè)置并發(fā)線程數(shù)量。

          特點

          CMS并不是獨占的回收器,也就說CMS回收的過程中,應(yīng)用程序仍然在不停的工作,又會有新的垃圾不斷的產(chǎn)生,所以在使用CMS的過程中應(yīng)該確保應(yīng)用程序的內(nèi)存足夠可用。

          CMS不會等到應(yīng)用程序飽和的時候才去回收垃圾,而是在某一閥值的時候開始回收,回收閥值可用指定的參數(shù)進行配置:-XX:CMSInitiatingoccupancyFraction來指定,默認為68,也就是說當老年代的空間使用率達到68%的時候,會執(zhí)行CMS回收。

          如果內(nèi)存使用率增長的很快,在CMS執(zhí)行的過程中,已經(jīng)出現(xiàn)了內(nèi)存不足的情況,此時CMS回收就會失敗,虛擬機將啟動老年代串行回收器;SerialOldGC進行垃圾回收,這會導(dǎo)致應(yīng)用程序中斷,直到垃圾回收完成后才會正常工作。

          這個過程GC的停頓時間可能較長,所以-XX:CMSInitiatingoccupancyFraction的設(shè)置要根據(jù)實際的情況。

          標記清除法有個缺點就是存在內(nèi)存碎片的問題,那么CMS有個參數(shù)設(shè)置-XX:+UseCMSCompactAtFullCollecion可以使CMS回收完成之后進行一次碎片整理

          -XX:CMSFullGCsBeforeCompaction參數(shù)可以設(shè)置進行多少次CMS回收之后,對內(nèi)存進行一次壓縮

          G1 回收器

          篇幅太長,我們下篇文章講解,另外,大家可以關(guān)注公眾號Java技術(shù)?;貜?fù)jvm46可以獲取一份JVM調(diào)優(yōu)指南。

          最近熱文:

          1、我用 Java 8 寫了一段邏輯,同事直呼看不懂

          2、Spring Boot 學(xué)習(xí)筆記,這個太全了!

          3、吊打 Tomcat ,Undertow 性能很炸!!

          4、Spring Boot 太狠了,一次發(fā)布 3 個版本!

          5、Spring Boot 如何快速集成 Redis?

          6、《Java開發(fā)手冊(嵩山版)》最新發(fā)布

          7、Spring Boot Redis 實現(xiàn)分布式鎖,真香!

          8、國人開源了一款小而全的 Java 工具類庫!

          9、國人開源了一款超好用的 Redis 客戶端!!

          10、同事寫了個隱藏 bug,我排查了 3 天!

          掃碼關(guān)注Java技術(shù)棧公眾號閱讀更多干貨。

          點擊「閱讀原文」獲取面試題大全~
          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩淫乱无码视频播放 | 久久成年人电影 | 亚洲欧洲在线观看 | 欧美激情综合网 | 久久久欧美精品sm网站 |