讓JVM按照預(yù)期GC

加入笨神(公眾號:你假笨)帶頭創(chuàng)建的JVMPocket群已經(jīng)有一段時間了,有幸得到笨神指導(dǎo)一二塘揣,學(xué)到了不少東西辛掠,也糾正了自己對JVM一些誤解,還能給群里一些朋友提出的問題給出指引进陡,榮幸榮幸愿阐;JVM博大精深,網(wǎng)上對它的解釋和認(rèn)知魚龍混雜趾疚,如果沒有深厚的功底很難辨別真假缨历;不用擔(dān)心,每個行業(yè)總有一些大牛是讓我們凡人膜拜的糙麦,JVM界公認(rèn)的大牛就是rednaxelaFX了辛孵,圈子人稱R大,且這么評價他:

  • R大說的是對的赡磅;
  • R大說的是對的魄缚;
  • R大說的是對的;

R大確實牛逼焚廊,先show一下他工作履歷:淘寶JVM組冶匹,美國OracleJVM組,Azul-ZingVM項目組咆瘟;R大不僅牛逼嚼隘,還非常謙虛活躍,在知乎上@他的問題袒餐,基本上都能得到他非常非常非常詳盡的解答嗓蘑,對JVM有興趣的朋友,強(qiáng)烈推薦關(guān)注他的知乎匿乃;另外桩皿,一些關(guān)注JVM的朋友基本上都看了周志明的<<深入理解Java虛擬機(jī)>>,R大對這本書一些有問題的地方也給出了更正幢炸,有興趣的朋友可以看看泄隔,請點(diǎn)擊傳送門

讓JVM按照預(yù)期GC

說起在JVMPocket里事情太多太多了宛徊,今天只說一下入群第一天笨神給我們出的一道題目:寫出讓JVM先3次YoungGC再1次CMS GC的代碼佛嬉;JVM比較復(fù)雜逻澳,很少有人能深入了解它,對絕大部分程序員來說JVM都是黑盒子暖呕;那么對我們這些不是專門從事JVM工作的程序員來說斜做,了解它的第一步就是:知道它大概怎么運(yùn)行,讓它按照自己的方式運(yùn)行湾揽;所以笨神的這道題目很有價值瓤逼,下面給出我的答案,源碼如下:

public class CmsGcTest {

    private static final int _1M = 1*1024*1024;
    private static final int _8M = 8*1024*1024;

    public static void main(String[] args) {

        // 預(yù)期YoungGC的次數(shù)
        int ygcTime = 3;

        for (int i=0; i<ygcTime; i++){
            // 由于Eden區(qū)設(shè)置為8M, 所以分配8個1M就會導(dǎo)致一次YoungGC
            for(int j=0; j<8; j++){
                byte[] tmp = new byte[_1M];
            }
        }

        for(int j=0; j<3; j++) {
            // 對象超過了Eden區(qū), 所以直接在Old區(qū)分配; 
            byte[] tmp = new byte[_8M];
        }

        try {
            // sleep一段時間是為了讓CMS GC線程能夠有足夠的時間檢測到Old區(qū)達(dá)到了觸發(fā)CMS GC的條件库物,CMS GC線程默認(rèn)2s掃描一次霸旗,可以通過參數(shù)CMSWaitDuration配置,例如-XX:CMSWaitDuration=3000
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

程序配套的JVM參數(shù):
-verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xmx40m -Xms40m -Xmn10m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly
說明:這樣配置后戚揭,Eden區(qū)8M诱告,S0/S1區(qū)各1M,old區(qū)30M民晒,且當(dāng)Old區(qū)占用60%就達(dá)到觸發(fā)CMS GC的條件精居;示例代碼中3次分配總計3*8M=24M>30*60%,達(dá)到了觸發(fā)CMS GC的條件潜必;

一點(diǎn)點(diǎn)瑕疵

這段代碼依然有一點(diǎn)點(diǎn)遺憾靴姿,為了達(dá)到觸發(fā)CMS GC的條件,每次分配的對象不能小于Eden區(qū)的大泄伪恪(在這段代碼中每次分配8M)空猜,如果要求Old區(qū)的大小在滿足不大于Eden區(qū)的大小同樣能達(dá)到需求,怎么辦恨旱?

更完美的方案

這里利用一個JVM參數(shù)PretenureSizeThreshold實現(xiàn)更完美的方案辈毯;用法:-XX:PretenureSizeThreshold=2M,含義是:當(dāng)分配的對象超過設(shè)定值時不在Eden區(qū)分配搜贤,直接在Old區(qū)分配谆沃;

public class CmsGcTest {

    private static final int _1M = 1*1024*1024;
    private static final int _2M = 2*1024*1024;

    public static void main(String[] args) {
        ygc(3);
        cmsGc(1);
        // 在這里想怎么觸發(fā)GC就怎么調(diào)用ygc()和cmsGc()兩個方法
    }

    /**
     * @param n 預(yù)期發(fā)生n次young gc
     */
    private static void ygc(int n){
        for (int i=0; i<n; i++){
            // 由于Eden區(qū)設(shè)置為8M, 所以分配8個1M就會導(dǎo)致一次YoungGC
            for(int j=0; j<8; j++){
                byte[] tmp = new byte[_1M];
            }
        }
    }

    /**
     * @param n 預(yù)期發(fā)生n次CMS gc
     */
    private static void cmsGc(int n){
        for (int i=0; i<n; i++){
            for(int j=0; j<3; j++) {
                // 由于設(shè)置了-XX:PretenureSizeThreshold=2M, 所以分配的2M對象不會在Eden區(qū)分配而是直接在Old區(qū)分配
                byte[] tmp = new byte[_2M];
            }
            try {
                // sleep10秒是為了讓CMS GC線程能夠有足夠的時間檢測到Old區(qū)達(dá)到了觸發(fā)CMS GC的條件并完成CMS GC, CMS GC線程默認(rèn)2s掃描一次,可以通過參數(shù)CMSWaitDuration配置仪芒,例如-XX:CMSWaitDuration=3000
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

程序配套的JVM參數(shù):
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xmx20m -Xms20m -Xmn10m -XX:PretenureSizeThreshold=2M -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseCMSInitiatingOccupancyOnly
說明:這樣配置后唁影,Eden區(qū)8M,S0/S1區(qū)各1M掂名,old區(qū)10M据沈,且當(dāng)Old區(qū)占用60%就達(dá)到觸發(fā)CMS GC的條件;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饺蔑,一起剝皮案震驚了整個濱河市锌介,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖孔祸,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隆敢,死亡現(xiàn)場離奇詭異,居然都是意外死亡崔慧,警方通過查閱死者的電腦和手機(jī)拂蝎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惶室,“玉大人温自,你說我怎么就攤上這事∧吹樱” “怎么了捣作?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵誉结,是天一觀的道長鹅士。 經(jīng)常有香客問我,道長惩坑,這世上最難降的妖魔是什么掉盅? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮以舒,結(jié)果婚禮上趾痘,老公的妹妹穿的比我還像新娘。我一直安慰自己蔓钟,他們只是感情好永票,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著滥沫,像睡著了一般侣集。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兰绣,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天世分,我揣著相機(jī)與錄音,去河邊找鬼缀辩。 笑死臭埋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的臀玄。 我是一名探鬼主播瓢阴,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼健无!你這毒婦竟也來了荣恐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤睬涧,失蹤者是張志新(化名)和其女友劉穎募胃,沒想到半個月后旗唁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痹束,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年检疫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祷嘶。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡屎媳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出论巍,到底是詐尸還是另有隱情烛谊,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布嘉汰,位于F島的核電站丹禀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鞋怀。R本人自食惡果不足惜双泪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望密似。 院中可真熱鬧焙矛,春花似錦、人聲如沸残腌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抛猫。三九已至蟆盹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邑滨,已是汗流浹背日缨。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掖看,地道東北人匣距。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像哎壳,于是被迫代替她去往敵國和親毅待。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 原文閱讀 前言 這段時間懈怠了归榕,罪過尸红! 最近看到有同事也開始用上了微信公眾號寫博客了,挺好的~給他們點(diǎn)贊,這博客我...
    碼農(nóng)戲碼閱讀 5,948評論 2 31
  • 作者:一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-12】 更新日志 日期更新內(nèi)容備注 2017-11-12新建文章初版 ...
    beneke閱讀 2,184評論 0 7
  • 參數(shù)設(shè)置 在Java虛擬機(jī)的參數(shù)中外里,有3種表示方法用“ps -ef |grep "java"命令怎爵,可以得到當(dāng)前Ja...
    九問閱讀 9,115評論 2 52
  • 轉(zhuǎn)載blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile閱讀 5,353評論 1 56
  • JVM架構(gòu) 當(dāng)一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))盅蝗,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,648評論 0 7