欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM GC 垃圾收集梳理總結(jié)

 更新時(shí)間:2022年07月08日 08:52:10   作者:? 我犟不過你??  
這篇文章主要介紹了JVM GC 垃圾收集梳理總結(jié),GC是一種自動(dòng)的存儲(chǔ)管理機(jī)制。當(dāng)一些被占用的內(nèi)存不再需要時(shí),就應(yīng)該予以釋放,這種存儲(chǔ)資源管理,稱為垃圾回收

什么是垃圾?

對于程序匯總分配的內(nèi)存,當(dāng)使用完成后,這部分內(nèi)存就會(huì)成為垃圾,需要對其進(jìn)行釋放,否則,這部分內(nèi)存將無法被重復(fù)利用,最終造成內(nèi)存泄漏。

什么是GC?

GC是一種自動(dòng)的存儲(chǔ)管理機(jī)制。當(dāng)一些被占用的內(nèi)存不再需要時(shí),就應(yīng)該予以釋放。這種存儲(chǔ)資源管理,稱為垃圾回收。

對于java而言,是自動(dòng)進(jìn)行垃圾回收的。

如何發(fā)現(xiàn)垃圾?

既然要實(shí)現(xiàn)垃圾的自動(dòng)回收,那么第一件事就是找到垃圾,那么如何發(fā)現(xiàn)垃圾呢?其實(shí)就是判斷這個(gè)對象是否存活。

常見的兩種方式判斷

  • 1)引用計(jì)數(shù)法(reference count)
  • 2)根可達(dá)性算法(root searching)
名稱實(shí)現(xiàn)思想優(yōu)點(diǎn)缺點(diǎn)
引用計(jì)數(shù)法給每個(gè)對象添加一個(gè)引用計(jì)數(shù)器,當(dāng)存在一個(gè)引用時(shí),就加1,當(dāng)一個(gè)引用失效時(shí),就減1。判定效率高1、無法解決相互引用、循環(huán)引用的問題。 2、存儲(chǔ)空間開銷:需要空間存儲(chǔ)計(jì)數(shù)器。 3、時(shí)間開銷:需要處理計(jì)數(shù)器的增加和減少。
根可達(dá)性算法通過一系列名為”GC Roots”的對象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索所走過的路徑稱為引用鏈(Reference Chain),當(dāng)一個(gè)對象到GC Roots沒有任何引用鏈相連時(shí),則證明此對象是不可用的。解決了循環(huán)引用的問題實(shí)現(xiàn)較復(fù)雜,增加了計(jì)算成本。

引用計(jì)數(shù)法(reference count)的循環(huán)引用、相互引用: 沒有外部引用,但是本身的計(jì)數(shù)器又不為0。

根可達(dá)性算法 由于引用計(jì)數(shù)法存在的問題,所有主流的jvm都不使用引用計(jì)數(shù)法,而是采用根可達(dá)性算法

如上圖,帶有GCRoots的對象表示正在被引用,而其他的對象雖然相互間有引用,但是沒有根節(jié)點(diǎn),仍然會(huì)被刪除。

GCRoots對象: 哪些對象可以成為GCRoots呢?jvm中主要針對堆內(nèi)的內(nèi)存進(jìn)行垃圾回收,而在虛擬機(jī)棧、本地方法棧和方法區(qū)內(nèi)的對象則不會(huì)被回收,通常選擇這三個(gè)區(qū)域的對象作為GCRoots。

在jvm中主要有以下四種,在方法區(qū)存在兩種:

  • 1)虛擬機(jī)棧中引用的對象:虛擬機(jī)棧幀中的局部變量表所引用的對象
  • 2)本地方法棧中引用的對象:JNI (Native方法)引用的對象。
  • 3)方法區(qū)中類靜態(tài)和常量對象:靜態(tài)變量常量引用的對象。

以下圖來展示在JVM內(nèi)存模型(JMM)的GCRoots:

 在根可達(dá)性算法中,所有的引用都是強(qiáng)引用,下面具體分析下jvm中的四種引用。

四種引用: 參考:分享JVM 的四種引用方式

名稱定義特點(diǎn)回收
強(qiáng)引用強(qiáng)引用就是引用了通過new 的方式創(chuàng)建的對象。是指創(chuàng)建一個(gè)對象并把這個(gè)對象賦給一個(gè)引用變量;在root搜索算法的里面,說的引用都指的是強(qiáng)引用關(guān)系。GC時(shí),永遠(yuǎn)不會(huì)被回收,導(dǎo)致OOM的主要原因1、引用消失(比如方法執(zhí)行完) 2、將引用變量設(shè)置為null
軟引用如果一個(gè)對象具有軟引用,內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對象的內(nèi)存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存,比如網(wǎng)頁緩存、圖片緩存等。使用軟引用能防止內(nèi)存泄露,增強(qiáng)程序的健壯性。Java中,用SoftRefrence表示弱引用。內(nèi)存不足時(shí)(自動(dòng)觸發(fā)GC),會(huì)被回收內(nèi)存不足時(shí),觸發(fā)自動(dòng)回收
弱引用引用也是用來描述非必需對象的,當(dāng)JVM進(jìn)行垃圾回收時(shí),無論內(nèi)存是否充足,都會(huì)回收被弱引用關(guān)聯(lián)的對象。在java中,用java.lang.ref.WeakReference類來表示無論內(nèi)存是否充足,只要進(jìn)行GC,都會(huì)被回收只要進(jìn)行GC,都會(huì)被回收
虛引用虛引用和前面的軟引用、弱引用不同,它并不影響對象的生命周期。在java中用java.lang.ref.PhantomReference類表示。如果一個(gè)對象與虛引用關(guān)聯(lián),則跟沒有引用與之關(guān)聯(lián)一樣,在任何時(shí)候都可能被垃圾回收器回收。 要注意的是,虛引用必須和引用隊(duì)列關(guān)聯(lián)使用,設(shè)置虛引用關(guān)聯(lián)的唯一目的,就是在這個(gè)對象被收集器回收的時(shí)候收到一個(gè)系統(tǒng)通知或者后續(xù)添加進(jìn)一步的處理。Java技術(shù)允許使用finalize()方法在垃圾收集器將對象從內(nèi)存中清除之前做必要的清理工作。如同虛設(shè),和沒有引用沒什么區(qū)別任何時(shí)候都可能被回收

垃圾如何處理?

我們通過上面學(xué)到的根可達(dá)性算法可以發(fā)現(xiàn)垃圾的所在,那么jvm是如何進(jìn)行垃圾回收的呢?通過jvm提供的垃圾收集器(GC) 。

目前有以下種類的垃圾收集器,其中虛線表示垃圾收集器可以進(jìn)行組合使用:

常見的垃圾收集算法

標(biāo)記清除(mark sweep) :位置不連續(xù) 產(chǎn)生碎片 效率偏低(兩遍掃描) 拷貝算法 (copying) :沒有碎片,浪費(fèi)空間 標(biāo)記壓縮(mark compact) :沒有碎片,效率偏低(兩遍掃描,指針需要調(diào)整)

標(biāo)記清除(mark sweep)

顧名思義,標(biāo)記清除算法分為兩個(gè)階段標(biāo)記(mark) 和清除(sweep) 。

標(biāo)記: Collector從引用根結(jié)點(diǎn)開始遍歷,標(biāo)記所有被引用的對象。一般是在對象的Header中記錄為可達(dá)對象。

清除: Collector對堆內(nèi)存從頭到尾進(jìn)行線性的遍歷,如果發(fā)現(xiàn)某個(gè)對象在其Header中沒有標(biāo)記為可達(dá)對象,則將其回收。

對所有能找到根節(jié)點(diǎn)引用的內(nèi)存空間進(jìn)行標(biāo)記,清除沒有找到根節(jié)點(diǎn)的內(nèi)存空間,其大概實(shí)現(xiàn)過程如下:

缺點(diǎn) :

  • 1)STW(stop the word),回收時(shí),應(yīng)用掛起。
  • 2)內(nèi)存越大,效率越多,需要掃描的時(shí)間越長。
  • 3)內(nèi)存碎片化,會(huì)導(dǎo)致無法裝下新申請的對象,整體內(nèi)存是足夠的,但并非連續(xù)的。

拷貝算法 (copying)

拷貝算法將內(nèi)存空間劃分為兩個(gè)區(qū)間,在任意時(shí)間點(diǎn),所有動(dòng)態(tài)分配的對象都只能分配在其中一個(gè)區(qū)間(稱為活動(dòng)區(qū)間),而另外一個(gè)區(qū)間(稱為空閑區(qū)間)則是空閑的。

當(dāng)活動(dòng)區(qū)間的內(nèi)存占滿時(shí),接下來GC線程會(huì)將活動(dòng)區(qū)間內(nèi)的存活對象,全部復(fù)制到空閑區(qū)間,且嚴(yán)格按照內(nèi)存地址依次排列,與此同時(shí),GC線程將更新存活對象的內(nèi)存引用地址指向新的內(nèi)存地址。

其大概過程如下圖所示:

缺點(diǎn) 浪費(fèi)內(nèi)存,并且存活對象越多的情況下,效率越低。

標(biāo)記壓縮/標(biāo)記整理(mark compact)

標(biāo)記過程仍然和標(biāo)記-清除一樣,但后續(xù)步驟不是直接對可回收對象進(jìn)行清理,而是讓所有存活的對象都向一端移動(dòng),然后直接清理端邊界以外的內(nèi)存。

實(shí)現(xiàn)過程大概如下:

缺點(diǎn) 效率不高,除了要標(biāo)記存活對象,還要整理存活對象的引用地址,效率低于復(fù)制算法。

總結(jié) 以上三種算法都是根據(jù)根可達(dá)性算法實(shí)現(xiàn)的。當(dāng)開始GC時(shí),三種算法都會(huì)造成STW(stop the world)。

JVM的內(nèi)存模型如何實(shí)現(xiàn)垃圾回收?分代模型

文章前面介紹了簡單很多種垃圾收集器,不同的垃圾收集器有不同的分代模型:

  • 1)除Epsilon、ZGC、Shenandoah之外的GC都是使用邏輯分代模型
  • 2)G1是邏輯分代,物理不分代
  • 3)除1)2)之外不僅邏輯分代,而且物理分代

分代模型:

上圖中的分代模型有些需要特別關(guān)注的點(diǎn):

  • 1)整個(gè)分代模型的組成:新生代 + 老年代 + 永久代(jdk1.7)/元空間(jdk1.8) 永久代、元空間:Class 永久代:必須指定大小限制 元空間:可以設(shè)置大小,也可以不設(shè)置,無上限(受限于物理內(nèi)存) 字符串常量池: jdk1.7 - 永久代,jdk1.8 - 堆 MethodArea(方法區(qū))邏輯概念:永久代、元數(shù)據(jù)
  • 2)新生代: Eden + 2個(gè)suvivor區(qū) YGC回收之后,大多數(shù)的對象會(huì)被回收,活著的進(jìn)入s0 再次YGC,活著的對象eden + s0 -> s1 再次YGC,活著的對象eden + s1 -> s0 年齡足夠 -> 老年代 (通常15,對象頭Mark Word 的age只有4bit,最大是15 、CMS 6) suvivor區(qū)裝不下 -> 老年代
  • 3)老年代 老年代滿了FGC Full GC(STW)

GC Tuning 盡量減少FGC MinorGC = YGC MajorGC = FGC

到此這篇關(guān)于JVM GC 垃圾收集梳理總結(jié)的文章就介紹到這了,更多相關(guān)JVM GC 垃圾收集 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis中association和collection的使用與區(qū)別

    mybatis中association和collection的使用與區(qū)別

    在 MyBatis 中,<association>?和?<collection>?是用于配置結(jié)果映射中關(guān)聯(lián)關(guān)系的兩個(gè)元素,本文主要介紹了mybatis中<association>和<collection>的使用與區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • SpringBoot整合Redis正確的實(shí)現(xiàn)分布式鎖的示例代碼

    SpringBoot整合Redis正確的實(shí)現(xiàn)分布式鎖的示例代碼

    這篇文章主要介紹了SpringBoot整合Redis正確的實(shí)現(xiàn)分布式鎖的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 實(shí)例講解JAVA設(shè)計(jì)模式之備忘錄模式

    實(shí)例講解JAVA設(shè)計(jì)模式之備忘錄模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之備忘錄模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java實(shí)現(xiàn)企業(yè)發(fā)放的獎(jiǎng)金根據(jù)利潤提成問題

    Java實(shí)現(xiàn)企業(yè)發(fā)放的獎(jiǎng)金根據(jù)利潤提成問題

    這篇文章主要介紹了請利用數(shù)軸來分界,定位。注意定義時(shí)需把獎(jiǎng)金定義成長整型,需要的朋友可以參考下
    2017-02-02
  • Java中超高頻常見字符操作合集(建議收藏)

    Java中超高頻常見字符操作合集(建議收藏)

    這篇文章主要為大家詳細(xì)介紹了Java中超高頻常見字符操作合集,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)java有一定的幫助,需要的小伙伴可以參考下
    2023-10-10
  • 搜索一文入門ElasticSearch(節(jié)點(diǎn) 分片 CRUD 倒排索引 分詞)

    搜索一文入門ElasticSearch(節(jié)點(diǎn) 分片 CRUD 倒排索引 分詞)

    這篇文章主要為大家介紹了搜索一文入門ElasticSearch(節(jié)點(diǎn) 分片 CRUD 倒排索引 分詞)的基礎(chǔ)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 解決問題:Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources

    解決問題:Failed to execute goal org.apache.m

    這篇文章主要給大家介紹了關(guān)于解決問題:Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources的相關(guān)資料,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • 詳解spring boot中使用JdbcTemplate

    詳解spring boot中使用JdbcTemplate

    JdbcTemplate 是在JDBC API基礎(chǔ)上提供了更抽象的封裝,并提供了基于方法注解的事務(wù)管理能力。 通過使用SpringBoot自動(dòng)配置功能并代替我們自動(dòng)配置beans,下面給大家介紹spring boot中使用JdbcTemplate相關(guān)知識(shí),一起看看吧
    2017-04-04
  • Maven安裝與配置及Idea配置Maven的全過程

    Maven安裝與配置及Idea配置Maven的全過程

    Maven是一個(gè)項(xiàng)目管理工具,可以對Java項(xiàng)目進(jìn)行自動(dòng)化的構(gòu)建和依賴管理,下面這篇文章主要給大家介紹了關(guān)于Maven安裝與配置及Idea配置Maven的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • Java 數(shù)據(jù)庫連接池 Tomcat介紹

    Java 數(shù)據(jù)庫連接池 Tomcat介紹

    這篇文章主要給大家分享了 Java 數(shù)據(jù)庫連接池 Tomcat介紹,omcat 是一個(gè)小型的輕量級應(yīng)用服務(wù)器,在中小型系統(tǒng)和并發(fā)訪問用戶不是很多的場合下被普遍使用,是開發(fā)和調(diào)試JSP 程序的首選。下面來看看文章內(nèi)容的詳細(xì)介紹吧
    2021-11-11

最新評論