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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM 调优实战--常见的垃圾回收算法及垃圾收集器组合

發(fā)布時(shí)間:2025/1/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM 调优实战--常见的垃圾回收算法及垃圾收集器组合 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么是垃圾

C語言申請(qǐng)內(nèi)存:malloc free

C++: new delete

c/C++ 手動(dòng)回收內(nèi)存

Java: new ?

自動(dòng)內(nèi)存回收,編程上簡(jiǎn)單,系統(tǒng)不容易出錯(cuò),手動(dòng)釋放內(nèi)存,容易出兩種類型的問題:

  • 忘記回收

  • 多次回收

  • 沒有任何引用指向的一個(gè)對(duì)象或者多個(gè)對(duì)象(循環(huán)引用)

    如何定位垃圾

    ①引用計(jì)數(shù)法

    ②跟可達(dá)算法

    常見的垃圾回收算法

  • 標(biāo)記清除 - 位置不連續(xù) 產(chǎn)生碎片 效率偏低(兩遍掃描)

  • 拷貝算法 - 沒有碎片,浪費(fèi)空間

  • 標(biāo)記壓縮 - 沒有碎片,效率偏低(兩遍掃描,指針需要調(diào)整)

  • JVM內(nèi)存分代模型

    jdk1.7永久代存放的是各種Class文件,如使用Spring等框架會(huì)產(chǎn)生大量代理對(duì)象,它們的Class對(duì)象就存放在永久代中。

    字符串常量:1.7是存放在永久代方法區(qū)MethodArea中,1.8存放在堆中。

    MethodArea方法區(qū):

    ①1.7叫做Perm Generation,1.8叫做Metaspace元數(shù)據(jù)區(qū)。

    ②里面存放的是class的元信息,代碼的編譯信息,各種層次信息,JIT編譯信息(JNI)等凡是跟JVM自身的class無關(guān)的其他信息都存放在方法區(qū)這個(gè)邏輯分區(qū)里面。

    ③在1.7版本,必須指定固定大小,而且很容易溢出。1.8之后內(nèi)存的大小設(shè)置受限于物理內(nèi)存,既可以設(shè)置也可以不設(shè)置,不設(shè)置理論上在物理內(nèi)存范圍內(nèi)無上限。

    堆內(nèi)存:包括年輕代和老年代

    堆外內(nèi)存:包括永久代和元數(shù)據(jù)區(qū)(曾用名:方法區(qū))

  • 部分垃圾回收器使用的模型

    除Epsilon ZGC Shenandoah之外的GC都是使用邏輯分代模型

    G1是邏輯分代,物理不分代

    除此之外不僅邏輯分代,而且物理分代

  • 新生代 + 老年代 + 永久代(1.7)/ 元數(shù)據(jù)區(qū)(1.8) Metaspace

  • 永久代 元數(shù)據(jù) - Class

  • 永久代必須指定大小限制 ,元數(shù)據(jù)可以設(shè)置,也可以不設(shè)置,無上限(受限于物理內(nèi)存)

  • 字符串常量 1.7 - 永久代,1.8 - 堆

  • MethodArea邏輯概念 - 永久代、元數(shù)據(jù)

  • 新生代 = Eden + 2個(gè)suvivor區(qū)

  • YGC回收之后,大多數(shù)的對(duì)象會(huì)被回收,活著的進(jìn)入s0

  • 再次YGC,活著的對(duì)象eden + s0 -> s1

  • 再次YGC,eden + s1 -> s0

  • 年齡足夠 -> 老年代 (15 CMS 6)

  • s區(qū)裝不下 -> 老年代

  • 老年代

  • 頑固分子

  • 老年代滿了FGC Full GC

  • GC Tuning (Generation)

  • 盡量減少FGC

  • MinorGC = YGC

  • MajorGC = FGC

  • 對(duì)象分配過程圖

  • 7.動(dòng)態(tài)年齡:(不重要) https://www.jianshu.com/p/989d3b06a49d

    8.分配擔(dān)保:(不重要) YGC期間 survivor區(qū)空間不夠了 空間擔(dān)保直接進(jìn)入老年代

    對(duì)象的分配過程:

    先在棧上跑,也就是棧上分配,看大不大,如果比較大的話就進(jìn)入Old區(qū),如果不是很大,就先進(jìn)行線程本地分配,?都進(jìn)入Eden區(qū),如果能清除就清除,不能清除就進(jìn)入S1,S1再來一遍,看年齡滿了沒有,年齡夠了就進(jìn)Old區(qū),如果不夠就進(jìn)入S2,就這樣循環(huán)往復(fù)。

    常見的垃圾收集器

    常見的使用組合是:

    ①Serial+Serial Old

    ②ParNew+CMS

    ③Parallel Scavenge+Parallel Old (PS+PO jdk1.8默認(rèn)的)

    ④G1

    這些使用組合沒有孰優(yōu)孰劣,得分不同的場(chǎng)景來選擇。比方說,老的機(jī)器上可能使用單線程的Serial更合適。

    ParNew+CMS是高響應(yīng),低停頓,但吞吐量降低。

  • JDK誕生 Serial追隨 提高效率,誕生了PS,為了配合CMS,誕生了PN,CMS是1.4版本后期引入,CMS是里程碑式的GC,它開啟了并發(fā)回收的過程,但是CMS毛病較多,因此目前任何一個(gè)JDK版本默認(rèn)是CMS 并發(fā)垃圾回收是因?yàn)闊o法忍受STW

  • Serial 年輕代 串行回收

  • PS 年輕代 并行回收

  • ParNew 年輕代 配合CMS的并行回收

  • SerialOld

  • ParallelOld

  • ConcurrentMarkSweep 老年代 并發(fā)的, 垃圾回收和應(yīng)用程序同時(shí)運(yùn)行,降低STW的時(shí)間(200ms) CMS問題比較多,所以現(xiàn)在沒有一個(gè)版本默認(rèn)是CMS,只能手工指定 CMS既然是MarkSweep,就一定會(huì)有碎片化的問題,碎片到達(dá)一定程度,CMS的老年代分配對(duì)象分配不下的時(shí)候,使用SerialOld 進(jìn)行老年代回收 想象一下: PS + PO -> 加內(nèi)存 換垃圾回收器 -> PN + CMS + SerialOld(幾個(gè)小時(shí) - 幾天的STW) 幾十個(gè)G的內(nèi)存,單線程回收 -> G1 + FGC 幾十個(gè)G -> 上T內(nèi)存的服務(wù)器 ZGC 算法:三色標(biāo)記 + Incremental Update

  • G1(10ms) 算法:三色標(biāo)記 + SATB

  • ZGC (1ms) PK C++ 算法:ColoredPointers + 寫屏障?

  • Shenandoah 算法:ColoredPointers + 讀屏障?

  • Eplison

  • PS 和 PN區(qū)別的延伸閱讀: ?https://docs.oracle.com/en/java/javase/13/gctuning/ergonomics.html#GUID-3D0BB91E-9BFF-4EBB-B523-14493A860E73

  • 垃圾收集器跟內(nèi)存大小的關(guān)系

  • Serial 幾十兆

  • PS 上百兆 - 幾個(gè)G

  • CMS - 20G

  • G1 - 上百G

  • ZGC - 4T

  • 1.8默認(rèn)的垃圾回收:PS + ParallelOld

    常見垃圾回收器組合參數(shù)設(shè)定:(1.8)

    • -XX:+UseSerialGC = Serial New (DefNew) + Serial Old

      • 小型程序。默認(rèn)情況下不會(huì)是這種選項(xiàng),HotSpot會(huì)根據(jù)計(jì)算及配置和JDK版本自動(dòng)選擇收集器

    • -XX:+UseParNewGC = ParNew + SerialOld

      • 這個(gè)組合已經(jīng)很少用(在某些版本中已經(jīng)廢棄)

      • https://stackoverflow.com/questions/34962257/why-remove-support-for-parnewserialold-anddefnewcms-in-the-future

    • -XX:+UseConc(urrent)MarkSweepGC = ParNew + CMS + Serial Old(jdk1.8的命令是UseConcMarkSweepGC,有的jdk版本是要加上紅色字體部分的。Serial Old是替補(bǔ))

    • -XX:+UseParallelGC = Parallel Scavenge + Parallel Old (1.8默認(rèn)) 【PS + SerialOld】

    • -XX:+UseParallelOldGC = Parallel Scavenge + Parallel Old

    • -XX:+UseG1GC = G1

    • Linux中沒找到默認(rèn)GC的查看方法,而windows中會(huì)打印UseParallelGC

      • java +XX:+PrintCommandLineFlags -version

      • 通過GC的日志來分辨

    • Linux下1.8版本默認(rèn)的垃圾回收器到底是什么?

      • 1.8.0_181 默認(rèn)(看不出來)Copy MarkCompact

      • 1.8.0_222 默認(rèn) PS + PO

    ?

    怎么調(diào)優(yōu)

    所謂調(diào)優(yōu),首先要確定追求的是啥?是吞吐量?jī)?yōu)先還是響應(yīng)時(shí)間優(yōu)先?或者是在滿足一定的響應(yīng)時(shí)間的前提下,要求達(dá)到一定的吞吐量?有的放矢才能做好調(diào)優(yōu)這活!

    如果是選擇吞吐量?jī)?yōu)先,一般選擇的是PS+PO這個(gè)組合

    如果是響應(yīng)時(shí)間優(yōu)先,比如網(wǎng)站,GUI,API服務(wù)等,1.8版本選擇G1垃圾收集器。

    ?

    ?

    jconsole遠(yuǎn)程連接

  • 程序啟動(dòng)加入?yún)?shù):

    java -Djava.rmi.server.hostname=192.168.17.11 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11111 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false XXX
  • 如果遭遇 Local host name unknown:XXX的錯(cuò)誤,修改/etc/hosts文件,把XXX加入進(jìn)去

    192.168.17.11 basic localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 ? ? ? ? localhost localhost.localdomain localhost6 localhost6.localdomain6
  • 關(guān)閉linux防火墻(實(shí)戰(zhàn)中應(yīng)該打開對(duì)應(yīng)端口)

    service iptables stop chkconfig iptables off #永久關(guān)閉
  • windows上打開 jconsole遠(yuǎn)程連接 192.168.17.11:11111

  • ?

    jprofiler (收費(fèi))

    arthas在線排查工具

    為什么需要在線排查? 在生產(chǎn)上我們經(jīng)常會(huì)碰到一些不好排查的問題,例如線程安全問題,用最簡(jiǎn)單的threaddump或者h(yuǎn)eapdump不好查到問題原因。為了排查這些問題,有時(shí)我們會(huì)臨時(shí)加一些日志,比如在一些關(guān)鍵的函數(shù)里打印出入?yún)?#xff0c;然后重新打包發(fā)布,如果打了日志還是沒找到問題,繼續(xù)加日志,重新打包發(fā)布。對(duì)于上線流程復(fù)雜而且審核比較嚴(yán)的公司,從改代碼到上線需要層層的流轉(zhuǎn),會(huì)大大影響問題排查的進(jìn)度。

    CMS

    CMS的問題

  • Memory Fragmentation

    -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction 默認(rèn)為0 指的是經(jīng)過多少次FGC才進(jìn)行壓縮

  • Floating Garbage

    Concurrent Mode Failure 產(chǎn)生:if the concurrent collector is unable to finish reclaiming the unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfiedwith the available free space blocks in the tenured generation, then theapplication is paused and the collection is completed with all the applicationthreads stopped

    解決方案:降低觸發(fā)CMS的閾值

    PromotionFailed

    解決方案類似,保持老年代有足夠的空間

    –XX:CMSInitiatingOccupancyFraction 92% 可以降低這個(gè)值,讓CMS保持老年代足夠的空間

  • 總結(jié)

    以上是生活随笔為你收集整理的JVM 调优实战--常见的垃圾回收算法及垃圾收集器组合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。