国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JVM實戰(zhàn)(24)——大對象優(yōu)化

這篇具有很好參考價值的文章主要介紹了JVM實戰(zhàn)(24)——大對象優(yōu)化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

作者簡介:大家好,我是smart哥,前中興通訊、美團架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO

聯(lián)系qq:184480602,加我進群,大家一起學(xué)習(xí),一起進步,一起對抗互聯(lián)網(wǎng)寒冬

學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實!

階段1、深入多線程

階段2、深入多線程設(shè)計模式

階段3、深入juc源碼解析

階段4、深入jdk其余源碼解析

階段5、深入jvm源碼解析

一、案例背景

本章將介紹一個因為大對象而導(dǎo)致的頻繁GC問題,其本質(zhì)也是開發(fā)童鞋在寫程序代碼時存在bug,進而導(dǎo)致出現(xiàn)JVM性能問題。

首先,這個系統(tǒng)上線之后發(fā)現(xiàn)一天的Full GC次數(shù)多達幾十次,通常來說,我們建議的一個比較良好的JVM性能,應(yīng)該是Full GC幾天才發(fā)生一次,或者最多一天發(fā)生幾次而已。

生產(chǎn)環(huán)境這個系統(tǒng)部署在2核4G的機器上,JVM參數(shù)如下:
-Xms=1536M -Xmx=1536M -Xmn=512M -Xss=256K -XX:SurvivorRatio=5 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=68 -XX:CMSParallelRemarkEnable -XX:UseCMSInitiatingOccupancyOnly -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:PrintHeapAtGC -Xloggc:gc.log

比較關(guān)鍵的幾個設(shè)置是:

  • -XX:SurvivorRatio=5:表示Eden:Survivor:Survivor=5:1:1
  • -XX:CMSInitiatingOccupancyFraction=68:表示一旦老年代內(nèi)存使用達到68%,就會觸發(fā)Full GC

此時,整個系統(tǒng)對應(yīng)的JVM內(nèi)存模型如下:

JVM實戰(zhàn)(24)——大對象優(yōu)化,jvm專題,jvm

1.1 存在問題

我們通過jstat進行分析,統(tǒng)計出的JVM性能如下:

  • 系統(tǒng)運行時間:6天
  • 6天內(nèi)的Full GC次數(shù)和總耗時:250次,70秒
  • 6天內(nèi)的Young GC次數(shù)和總耗時:26000次,1400秒

也就是說,平均每20s觸發(fā)一次Young GC,每30分鐘觸發(fā)一次Full GC。根據(jù)Eden區(qū)和老年代的空間可以估算,系統(tǒng)每秒鐘會產(chǎn)生約20MB對象進入Eden,每30分鐘會有約600MB對象進入老年代:

JVM實戰(zhàn)(24)——大對象優(yōu)化,jvm專題,jvm

根據(jù)參數(shù)-XX:CMSInitiatingOccupancyFraction=68,老年代內(nèi)存使用達到68%,就會觸發(fā)Full GC,一次Full GC時間約300ms。

二、大對象

2.1 優(yōu)化前

通過上述的案例背景介紹,我們首先想到的是會不會因為Survivor區(qū)太小,導(dǎo)致Young GC后的存活對象太多,放不下Survivor了,所以就一直有對象流入老年代,進而導(dǎo)致30分鐘后觸發(fā)Full GC?

但這只是推論,因為對象進入老年代也可能是因為動態(tài)年齡判斷規(guī)則,所以我們就需要通過工具在高峰期觀察JVM的內(nèi)存使用情況。

事實上,我們觀察到每次 Young GC后進入老年代的對象非常少,而且一次Young GC的存活對象也就是幾十MB,Survior區(qū)可以容納,偶爾觸發(fā)動態(tài)年齡判斷規(guī)則時,才有幾十MB對象進入老年代:

JVM實戰(zhàn)(24)——大對象優(yōu)化,jvm專題,jvm

因此,分析到這里就很奇怪了,因為通過jstat追蹤,并不是每次Young GC后都有幾十MB對象進入老年代,而是偶爾才有對象進入老年代,記住,是偶爾。

那么老年代里面到底為什么會有那么多對象呢?

我們觀察發(fā)現(xiàn),?系統(tǒng)運行一段時間后,突然間老年代中的對象就會增加五六百MB?。

答案已經(jīng)很明顯了——?大對象?!一定是系統(tǒng)運行時,每隔一段時間就會產(chǎn)生幾百兆的大對象,直接進入老年代,不會走年輕代的Eden區(qū),然后配合年輕代還偶爾會有幾十MB對象進入老年代,所以才30分鐘觸發(fā)一次Full GC:

JVM實戰(zhàn)(24)——大對象優(yōu)化,jvm專題,jvm

2.2 優(yōu)化后

了解了問題的所在,我們就開始針對這個案例進行優(yōu)化。首先,就是要確定這個大對象到底是什么?

我們采用jmap工具導(dǎo)出一份JVM內(nèi)存快照,然后通過jhat或者Visual VM之類的可視化工具進行分析,發(fā)現(xiàn)那幾百兆大對象就是從數(shù)據(jù)庫中查出的記錄,然后對SQL進行排查,發(fā)現(xiàn)某個SQL在一種特殊場景下會執(zhí)行類似SELECT * FROM的語句,導(dǎo)致一次性從數(shù)據(jù)庫中查出幾十萬條數(shù)據(jù)。

針對該問題,主要做以下幾點優(yōu)化:

  1. 解決程序bug,不允許全表查詢,這樣就避免了大對象直接進入老年代的問題;
  2. Survivor區(qū)明顯不夠,70MB的空間很容易觸發(fā)動態(tài)年齡判斷,所以為其分配更多空間。

優(yōu)化后的JVM參數(shù)如下:

-Xms=1536M -Xmx=1536M -Xmn=1024M -Xss=256K -XX:SurvivorRatio=5 -XX:PermSize=256M -XX:MaxPermSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=92 -XX:CMSParallelRemarkEnable -XX:UseCMSInitiatingOccupancyOnly -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:PrintHeapAtGC -Xloggc:gc.log

可以看到,新生代直接分配1G空間,其中Survivor各占150MB左右,此時Young GC過后的幾十MB存活對象一般就不會進入老年代了。

同時,調(diào)整參數(shù)-XX:CMSInitiatingOccupancyFraction=92,將比例提高至92%,避免老年代僅占62%就觸發(fā)Full GC。

最后,還設(shè)置永久代大小為256MB,因為默認(rèn)永久代就幾十MB,如果程序使用了反射等機制,很容
易被占滿。

經(jīng)過上述優(yōu)化,系統(tǒng)基本上每分鐘一次Young GC,幾天才會發(fā)生一個Full GC。

三、總結(jié)

本章,我們通過示例分析了大對象導(dǎo)致的頻繁Full GC問題,并一步一步展現(xiàn)了發(fā)現(xiàn)問題、分析問題、解決問題的思路。當(dāng)我們發(fā)現(xiàn)Young GC過后并不是每次都有很多存活對象進入老年代的時候,就要從別的角度考慮下到底為什么會有那么多存活對象進入老年代。文章來源地址http://www.zghlxwxcb.cn/news/detail-797608.html

到了這里,關(guān)于JVM實戰(zhàn)(24)——大對象優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • JVM實戰(zhàn)(23)——內(nèi)存碎片優(yōu)化

    JVM實戰(zhàn)(23)——內(nèi)存碎片優(yōu)化

    作者簡介:大家好,我是smart哥,前中興通訊、美團架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO 聯(lián)系qq:184480602,加我進群,大家一起學(xué)習(xí),一起進步,一起對抗互聯(lián)網(wǎng)寒冬 學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實! 階段1、深入多線程 階段2、深入多線程設(shè)計模式 階段3、深入juc源碼解析

    2024年01月18日
    瀏覽(53)
  • JVM實戰(zhàn)(25)——元數(shù)據(jù)區(qū)優(yōu)化

    JVM實戰(zhàn)(25)——元數(shù)據(jù)區(qū)優(yōu)化

    作者簡介:大家好,我是smart哥,前中興通訊、美團架構(gòu)師,現(xiàn)某互聯(lián)網(wǎng)公司CTO 聯(lián)系qq:184480602,加我進群,大家一起學(xué)習(xí),一起進步,一起對抗互聯(lián)網(wǎng)寒冬 學(xué)習(xí)必須往深處挖,挖的越深,基礎(chǔ)越扎實! 階段1、深入多線程 階段2、深入多線程設(shè)計模式 階段3、深入juc源碼解析

    2024年01月22日
    瀏覽(27)
  • JVM零基礎(chǔ)到高級實戰(zhàn)之對象存活算法引用計數(shù)法存在的特點分析

    JVM零基礎(chǔ)到高級實戰(zhàn)之對象存活算法引用計數(shù)法存在的特點分析 JVM零基礎(chǔ)到高級實戰(zhàn)之對象存活算法引用計數(shù)法存在的特點分析 優(yōu)點 引用計數(shù)收集器可以很快的執(zhí)行,交織在程序運行中。對程序需要不被長時間打斷的實時環(huán)境比較有利。 缺點 無法檢測出循環(huán)引用。如父對

    2024年02月15日
    瀏覽(22)
  • JAVA工程師面試專題-JVM篇

    目錄 一、運行時數(shù)據(jù)區(qū) 1、說一下JVM的主要組成部分及其作用? 2、說一下 JVM 運行時數(shù)據(jù)區(qū) ? 3、說一下堆棧的區(qū)別 4、成員變量、局部變量、類變量分別存儲在什么地方? 5、類常量池、運行時常量池、字符串常量池有什么區(qū)別? 6、JVM為什么使用元空間替換永久代 二、垃

    2024年02月21日
    瀏覽(16)
  • Jvm對象回收算法-JVM(九)

    Jvm對象回收算法-JVM(九)

    上篇文章介紹了jvm運行時候?qū)ο筮M入老年代的場景,以及如何避免頻繁fullGC。 Jvm參數(shù)設(shè)置-JVM(八) 老年代分配擔(dān)保機制 這個機制的目的是為了提升效率,在minorGC之前,會有三次判斷,之后再次minorGC速度會很快。 老年代剩余空間是否 大于 年輕代里現(xiàn)在所有對象 大于的話則

    2024年02月13日
    瀏覽(22)
  • JVM-JVM中對象的結(jié)構(gòu)

    JVM-JVM中對象的結(jié)構(gòu)

    對象內(nèi)存布局 對象里的三個區(qū): 對象頭(Header):Java對象頭占8byte。如果是數(shù)組則占12byte。因為JVM里數(shù)組size需要使用4byte存儲。 標(biāo)記字段MarkWord: 用于存儲對象自身的運行時數(shù)據(jù),它是synchronized實現(xiàn)輕量級鎖和偏向鎖的關(guān)鍵。 默認(rèn)存儲:對象HashCode、GC分代年齡、鎖狀態(tài)等

    2024年02月20日
    瀏覽(26)
  • Jvm創(chuàng)建對象之內(nèi)存分配-JVM(七)

    Jvm創(chuàng)建對象之內(nèi)存分配-JVM(七)

    上篇文章介紹了jvm創(chuàng)建,會校驗是否已加載類,沒有則加載,通過之前學(xué)的源碼,classLoader加載完之后,虛擬機開始給類分配內(nèi)存,指針移動分配和free鏈表分配,解決并發(fā)分配情況用cap和TLAB方法。之后設(shè)置對象頭部信息,有mark word線程鎖,分代年齡等,klass pointer。還有指針

    2024年02月13日
    瀏覽(25)
  • JVM系列(六) JVM 對象終結(jié)方法finalize

    我們有幾個特別容易混淆的final、finally、finalize, 他們之間的區(qū)別是什么? final 是java finally 是try-catch-finally finalize 是Object 根類的方法 今天我們著重講下 finalize方法 1.finalize方法的原理及調(diào)用 finalize方法也是Java中所有類中必有的方法,因為它是屬于Object根類的方

    2023年04月08日
    瀏覽(21)
  • JVM-JVM中對象的生命周期

    JVM-JVM中對象的生命周期

    申明:文章內(nèi)容是本人學(xué)習(xí)極客時間課程所寫,文字和圖片基本來源于課程資料,在某些地方會插入一點自己的理解,未用于商業(yè)用途,侵刪。 原資料地址:課程資料 對象的創(chuàng)建 常量池檢查 :檢查new指令是否能在常量池中定位到這個類的符號引用,檢查類之前是否被加載過

    2024年02月20日
    瀏覽(22)
  • JVM---理解jvm之對象已死怎么判斷?

    JVM---理解jvm之對象已死怎么判斷?

    目錄 引用計數(shù)算法 什么是引用 可達性分析算法(用的最多的) 定義:在對象中添加一個引用計數(shù)器,每當(dāng)有一個地方引用它時,計數(shù)器值就加一;當(dāng)引用失效時,計數(shù)器值就減一;任何時刻計數(shù)器為零的對象就是不可能再被使用的。 但是不能解決循環(huán)引用的問題,A引用

    2024年02月12日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包