日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM笔记详解之垃圾回收器

發布時間:2023/12/4 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM笔记详解之垃圾回收器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:什么是垃圾回收機制(GC)

在C/C++程序中,程序員在內存中主動開辟一段相應的空間來存值。由于內存是有限的,所以當程序不再需要使用該內存空間時,就需要銷毀對象并釋放其所占用的內存資源,好重新利用這段空間。在C/C++中,釋放無用內存空間的事情需要由程序員自己來處理。就是說當程序員認為空間沒用了,就手動地釋放其占用的內存。但是這樣顯然非常繁瑣,如果有所遺漏,就可能造成資源浪費甚至內存泄露。當軟件系統比較復雜,變量多的時候程序員往往就忘記釋放內存或者在不該釋放的時候釋放內存了。
有了GC,程序員就不需要再手動的去控制內存的釋放。當Java虛擬機(VM)或.NETCLR發覺內存資源緊張的時候,就會自動地去清理無用對象(沒有被引用到的對象)所占用的內存空間

二:需要GC的內存區域

jvm 中,程序計數器、虛擬機棧、本地方法棧都是隨線程而生隨線程而滅,棧幀隨著方法的進入和退出做入棧和出棧操作,實現了自動的內存清理,因此,我們的內存垃圾回收主要集中于 java 堆和方法區中,在程序運行期間,這部分內存的分配和使用都是動態的。

三:如何判斷一個對象是否存活(死的話就回收)

(1)引用計數:

每個對象有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。此方法簡單,無法解決對象相互循環引用的問題。

(2)可達性分析(Reachability Analysis):

從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。不可達對象。

3:java中可作為GC Root的對象有

1.虛擬機棧中引用的對象(本地變量表)
2.方法區中靜態屬性引用的對象
3. 方法區中常量引用的對象
4.本地方法棧中引用的對象(Native對象)

四:何時觸發GC

  • 程序調用System.gc時可以觸發
  • 系統自身來決定GC觸發的時機(Young GC,Old GC,FULL GC ,Mixed GC)
  • Young GC:
    新生代內存的垃圾收集事件稱為 Young GC(又稱 Minor GC),當 JVM 無法為新對象分配在新生代內存空間時總會觸發 Young GC。比如 Eden 區占滿時,新對象分配頻率越高,Young GC 的頻率就越高。Young GC 每次都會引起全線停頓(Stop-The-World),暫停所有的應用線程,停頓時間相對老年代 GC 造成的停頓,幾乎可以忽略不計。
  • Old GC:只清理老年代空間的 GC 事件,只有 CMS 的并發收集是這個模式
  • Full GC:清理整個堆的 GC 事件,包括新生代、老年代、元空間等
  • Mixed GC:清理整個新生代以及部分老年代的 GC,只有 G1 有這個模式。

五:GC做了什么事情

主要做了清理對象,整理內存的工作。Java堆分為新生代和老年代,采用了不同的回收方式。

六:GC常用的算法

1:簡介

GC常用算法有:標記-清除算法,標記-壓縮算法,復制算法,分代收集算法。
目前主流的JVM(HotSpot)采用的是分代收集算法。

2.標記-清除算法:

  • a.標記-清除算法:
    為每個對象存儲一個標記位,記錄對象的狀態(活著或是死亡)。分為兩個階段,一個是標記階段,這個階段內,為每個對象更新標記位,檢查對象是否死亡;第二個階段是清除階段,該階段對死亡的對象進行清除,執行 GC 操作。
  • 優點:
    最大的優點是,標記—清除算法中每個活著的對象的引用只需要找到一個即可,找到一個就可以判斷它為活的。此外,更重要的是,這個算法并不移動對象的位置。
  • 缺點:
    它的缺點就是效率比較低(遞歸與全堆對象遍歷)。每個活著的對象都要在標記階段遍歷一遍;所有對象都要在清除階段掃描一遍,因此算法復雜度較高。沒有移動對象,導致可能出現很多碎片空間無法利用的情況。

3:復制算法:

  • b.復制算法:
    該算法將內存平均分成兩部分,然后每次只使用其中的一部分,當這部分內存滿的時候,將內存中所有存活的對象復制到另一個內存中,然后將之前的內存清空,只使用這部分內存,循環下去。
    注意:
    這個算法與標記-整理算法的區別在于,該算法不是在同一個區域復制,而是將所有存活的對象復制到另一個區域內。
  • 優點:
    實現簡單;不產生內存碎片
  • 缺點:
    每次運行,總有一半內存是空的,導致可使用的內存空間只有原來的一半。(內存利用率不高)

4:標記整理算法

為了解決Copying算法的缺陷,充分利用內存空間,提出了Mark-Compact算法。該算法標記階段和Mark-Sweep一樣,但是在完成標記之后,它不是直接清理可回收對象,而是將存活對象都向一端移動,然后清理掉端邊界以外的內存。

5:分代收集算法:

現在的虛擬機垃圾收集大多采用這種方式,它根據對象的生存周期,將堆分為新生代(Young)和老年代(Tenure)。
在新生代中,由于對象生存期短,每次回收都會有大量對象死去,那么這時就采用復制算法。
老年代里的對象存活率較高,沒有額外的空間進行分配擔保,所以可以使用標記-整理 或者 標記-清除。(一般將占用內存較大的對象存放在老年代的內存中)
具體過程:新生代(Young)分為Eden區,From區與To區(也就是survive)

  • 當系統創建一個對象的時候,總是在Eden區操作,當這個區滿了,那么就會觸發一次YoungGC,也就是年輕代的垃圾回收。一般來說這時候不是所有的對象都沒用了,所以就會把還能用的對象復制到From區。
  • 這樣整個Eden區就被清理干凈了,可以繼續創建新的對象,當Eden區再次被用完,就再觸發一次YoungGC,然后呢,注意,這個時候跟剛才稍稍有點區別。這次觸發YoungGC后,會將Eden區與From區還在被使用的對象復制到To區。
  • 下一次YoungGC的時候,則是將Eden區與To區中的還在被使用的對象復制到From區。
  • 經過若干次YoungGC后,有些對象在From與To之間來回游蕩,這時候From區與To區亮出了底線(閾值),這些家伙要是到現在還沒掛掉,對不起,一起滾到(復制)老年代吧。
  • 老年代經過這么幾次折騰,也就扛不住了(空間被用完),好,那就來次集體大掃除(Full GC),也就是全量回收。如果Full GC使用太頻繁的話,無疑會對系統性能產生很大的影響。所以要合理設置年輕代與老年代的大小,盡量減少Full GC的操作。

七:垃圾回收器

1:概覽

垃圾回收器一般是分為年輕代何老年代的 需要搭配使用
如果說收集算法是內存回收的方法論,垃圾收集器就是內存回收的具體實現

2:Serial收集器

串行收集器是最古老,最穩定以及效率高的收集器
可能會產生較長的停頓(stop-the-world應用線程終止 啟動GC線程),只使用一個線程去回收
-XX:+UseSerialGC
新生代、老年代使用串行回收
新生代復制算法
老年代標記-壓縮

3:ParNew并行收集器

解決Serival單個線程回收效率低下的弊端,從而使用多線程
-XX:+UseParNewGC(new代表新生代,所以適用于新生代)
新生代并行
老年代串行
Serial收集器新生代的并行版本
在新生代回收時使用復制算法
多線程,需要多核支持
-XX:ParallelGCThreads 限制線程數量

4.Parallel收集器

Parallel收集器 和ParNew收集器類似,是一個新生代收集器。使用復制算法的并行多線程收集器。
該垃圾收集器,是JAVA虛擬機在Server模式下的默認值,使用Server模式后,Java虛擬機使用Parallel Scavenge收集器(新生代)+ Serial Old收集器(老年代)的收集器組合進行內存回收。
該收集器還有個特點就是“吞吐量優先”JVM自動調節參數,已達到預設的吞吐量,提升性能。

5:Parallel Old 收集器

老年代收集器,Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和“標記-整理”算法。這個收集器是在JDK 1.6中才開始提供的,在此之前,新生代的Parallel Scavenge收集器一直處于比較尷尬的狀態。原因是,如果新生代選擇了Parallel Scavenge收集器,老年代除了Serial Old(PS MarkSweep)收集器外別無選擇(還記得上面說過Parallel Scavenge收集器無法與CMS收集器配合工作嗎?)。由于老年代Serial Old收集器在服務端應用性能上的“拖累”,使用了Parallel Scavenge收集器也未必能在整體應用上獲得吞吐量最大化的效果,由于單線程的老年代收集中無法充分利用服務器多CPU的處理能力。直到Parallel Old收集器出現后,“吞吐量優先”收集器終于有了比較名副其實的應用組合,在注重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge加Parallel Old收集器。

6:CMS收集器(老年代收集器)

(1):簡介

Concurrent Mark Sweep 并發標記清除(應用程序線程和GC線程交替執行)
使用標記-清除算法
并發階段會降低吞吐量(停頓時間減少,吞吐量降低)
老年代收集器(新生代使用ParNew)
-XX:+UseConcMarkSweepGC
老年代收集器,它的主要適合場景是對響應時間的重要性需求 大于對吞吐量的要求,能夠承受垃圾回收線程和應用線程共享處理器資源,并且應用中存在比較多的長生命周期的對象的應用。CMS是用于對tenured generation的回收,也就是年老代的回收,目標是盡量減少應用的暫停時間,減少full gc發生的幾率,利用和應用程序線程并發的垃圾回收線程來標記清除年老代。在我們的應用中,因為有緩存的存在,并且對于響應時間也有比較高的要求,因此希 望能嘗試使用CMS來替代默認的server型JVM使用的并行收集器,以便獲得更短的垃圾回收的暫停時間,提高程序的響應性。

(2):CMS的運行過程

  • 1.初始標記(會產生全局停頓)
    根可以直接關聯到的對象
    速度快
  • 并發標記(和用戶線程一起)
    主要標記過程,標記全部對象
  • 重新標記 (會產生全局停頓)
    由于并發標記時,用戶線程依然運行,因此在正式清理前,再做修正
  • 并發清除(和用戶線程一起)
    基于標記結果,直接清理對象

    這里就能很明顯的看出,為什么CMS要使用標記清除而不是標記壓縮,如果使用標記壓縮,需要多對象的內存位置進行改變,這樣程序就很難繼續執行。但是標記清除會產生大量內存碎片,不利于內存分配。

(3):CMS收集器特點:

  • a:盡可能降低停頓會影響系統整體吞吐量和性能
    比如,在用戶線程運行過程中,分一半CPU去做GC,系統性能在GC階段,反應速度就下降一半
  • b:清理不徹底
    因為在清理階段,用戶線程還在運行,會產生新的垃圾,無法清理
  • c:CMS也提供了整理碎片的參數
    設置進行幾次Full GC后,進行一次碎片整理,整理過程是獨占的,會引起停頓時間變長
  • 總結
    CMS的提出是想改善GC的停頓時間,在GC過程中的確做到了減少GC時間,但是同樣導致產生大量內存碎片,又需要消耗大量時間去整理碎片,從本質上并沒有改善時間。

7:G1收集器

(1):簡介

  • G1(Garbage-First)是一款面向服務器的垃圾收集器,支持新生代和老年代空間的垃圾收集,主要針對配備多核處理器及大容量內存的機器。
  • 與CMS收集器相比G1收集器有以下特點:
    (1) 空間整合,G1收集器采用標記-整理算法,不會產生內存空間碎片。分配大對象時不會因為無法找到連續空間而提前觸發下一次GC。
    (2)可預測停頓,這是G1的另一大優勢,降低停頓時間是G1和CMS的共同關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為N毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已經是實時Java(RTSJ)的垃圾收集器的特征了。
  • G1 堆空間劃分
  • Region
    為實現大內存空間的低停頓時間的回收,將劃分為多個大小相等的 Region。每個小堆區都可能是 Eden 區,Survivor 區或者 Old 區,但是在同一時刻只能屬于某個代
    在邏輯上, 所有的 Eden 區和 Survivor 區合起來就是新生代,所有的 Old 區合起來就是老年代,且新生代和老年代各自的內存 Region 區域由 G1 自動控制,不斷變動。
  • G1 把堆內存劃分成一個個 Region 的意義在于:
    每次 GC 不必都去處理整個堆空間,而是每次只處理一部分 Region,實現大容量內存的 GC。
    通過計算每個 Region 的回收價值,包括回收所需時間、可回收空間,在有限時間內盡可能回收更多的垃圾對象,把垃圾回收造成的停頓時間控制在預期配置的時間范圍內,這也是 G1 名稱的由來:Garbage-First

(2):G1的幾個階段

初始標記(會有stw)
并發標記
最終標記
篩選回收

(3):相對于CMS的區別在:

  • G1在壓縮空間方面有優勢
  • G1通過將內存空間分成區域(Region)的方式避免內存碎片問題
  • Eden, Survivor, Old區不再固定、在內存使用效率上來說更靈活
  • G1可以通過設置預期停頓時間(Pause Time)來控制垃圾收集時間避免應用雪崩現象
  • G1在回收內存后會馬上同時做合并空閑內存的工作、而CMS默認是在STW(stop the world)的時候做
  • G1也會在Young GC中使用、而CMS只能在Old GC區使用
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的JVM笔记详解之垃圾回收器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。