逃逸分析

逃逸分析

在編程語言的編譯優(yōu)化原理中素跺,分析指針動態(tài)范圍的方法稱之為逃逸分析齐苛。通俗來講,當(dāng)一個對象的指針被多個方法或線程引用時胸嘁,我們稱這個指針發(fā)生了逃逸瓶摆。

常見的逃逸場景:全局變量賦值、方法返回值性宏、實例引用傳遞

public class A {

    public static B b;
    
    //給全局變量賦值群井,發(fā)生逃逸
    public void globalVariablePointerEscape(){
        b = new B();
    }

    //方法返回值,發(fā)生逃逸
    public B methodPointerEscape(){
        return new B();
    }

    //實例引用傳遞毫胜,發(fā)生逃逸
    public void instancePassPointerEscape(){
        methodPointerEscape().printClassName(this);
    }

}

public class B {

    public void printClassName(A a){
        System.out.println(a.getClass().getName());
    }

}

逃逸分析原理

我們知道Java對象是在堆里分配的书斜,在調(diào)用棧中,只保存了對象的指針酵使。當(dāng)對象不再使用后荐吉,需要依靠GC來遍歷引用樹并回收內(nèi)存,如果對象數(shù)量較多口渔,將給GC帶來較大壓力稍坯。因此,減少臨時對象在堆內(nèi)存分配的數(shù)量是最有效的優(yōu)化方法。

場景應(yīng)用一:棧上分配

其實瞧哟,在java應(yīng)用里普遍存在一種場景混巧。一般是在方法體內(nèi),聲明了一個局部變量勤揩,且該變量在方法執(zhí)行生命周期內(nèi)未發(fā)生逃逸(在方法體內(nèi)咧党,未將引用暴露給外面)。按照J(rèn)VM內(nèi)存分配機(jī)制陨亡,首先會在堆里創(chuàng)建變量類的實例傍衡,然后將返回的對象指針壓入調(diào)用棧,繼續(xù)執(zhí)行负蠕。這是優(yōu)化前蛙埂,JVM的處理方式。

  • 逃逸分析優(yōu)化 - 棧上分配

分析找到未逃逸的變量遮糖,將變量類的實例化內(nèi)存直接在棧里分配(無需進(jìn)入堆)绣的,分配完成后,繼續(xù)在調(diào)用棧內(nèi)執(zhí)行欲账,最后線程結(jié)束屡江,棧空間被回收赛不,局部變量對象也被回收惩嘉。對比可以看出,主要區(qū)別在椞吖剩空間直接作為臨時對象的存儲介質(zhì)文黎。從而減少了臨時對象在堆內(nèi)的分配數(shù)量。

應(yīng)用場景二:同步消除

在即使編譯器時殿较,如果發(fā)現(xiàn)不可能被共享的對象臊诊,則可以消除這些對象的鎖操作。

也許你會覺得奇怪斜脂,既然有些對象不可能被多線程訪問,那為什么要加鎖呢触机?寫代碼時直接不加鎖不就好了帚戳。但是有時,這些鎖并不是程序員所寫的儡首,有的是JDK實現(xiàn)中就有鎖的片任,比如Vector和StringBuffer這樣的類,它們中的很多方法都是有鎖的蔬胯。當(dāng)我們在一些不會有線程安全的情況下使用這些類的方法時对供,達(dá)到某些條件時,編譯器會將鎖消除來提高性能。

public class BufferTest {

    public static void main(String[] args){
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i ++){
            createStringBuffer("JVM", "EscapeAnalysis");
        }
        long end = System.currentTimeMillis();
        System.out.println("it takes " + (end - start) + " ms");

    }

    public static String createStringBuffer(String s1, String s2){
        StringBuffer sb = new StringBuffer();
        sb.append(s1);
        sb.append(s2);
        return sb.toString();
    }

}

優(yōu)化前:
it takes 867 ms
優(yōu)化后:
it takes 802 ms

基于逃逸分析产场,JVM可以判斷鹅髓,如果這個局部變量StringBuffer并沒有逃出它的作用域,那么可以確定這個StringBuffer并不會被多線程所訪問京景,那么就可以把這些多余的鎖給去掉來提高性能窿冯。

應(yīng)用場景三:標(biāo)量替換

Java虛擬機(jī)中的原始數(shù)據(jù)類型(int,long等數(shù)值類型以及reference類型等)都不能再進(jìn)一步分解确徙,它們就可以稱為標(biāo)量醒串。相對的,如果一個數(shù)據(jù)可以繼續(xù)分解鄙皇,那它稱為聚合量芜赌,Java中最典型的聚合量是對象。如果逃逸分析證明一個對象不會被外部訪問伴逸,并且這個對象是可分解的缠沈,那程序真正執(zhí)行的時候?qū)⒖赡懿粍?chuàng)建這個對象,而改為直接創(chuàng)建它的若干個被這個方法使用到的成員變量來代替违柏。拆散后的變量便可以被單獨分析與優(yōu)化博烂,可以各自分別在棧幀或寄存器上分配空間,原本的對象就無需整體分配空間了漱竖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末禽篱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子馍惹,更是在濱河造成了極大的恐慌躺率,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件万矾,死亡現(xiàn)場離奇詭異悼吱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)良狈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門后添,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人薪丁,你說我怎么就攤上這事遇西。” “怎么了严嗜?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵粱檀,是天一觀的道長。 經(jīng)常有香客問我漫玄,道長茄蚯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮渗常,結(jié)果婚禮上壮不,老公的妹妹穿的比我還像新娘。我一直安慰自己凳谦,他們只是感情好忆畅,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尸执,像睡著了一般家凯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上如失,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天绊诲,我揣著相機(jī)與錄音,去河邊找鬼褪贵。 笑死掂之,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脆丁。 我是一名探鬼主播世舰,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼槽卫!你這毒婦竟也來了跟压?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤歼培,失蹤者是張志新(化名)和其女友劉穎震蒋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躲庄,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡查剖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了噪窘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笋庄。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖倔监,靈堂內(nèi)的尸體忽然破棺而出直砂,到底是詐尸還是另有隱情,我是刑警寧澤丐枉,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站掘托,受9級特大地震影響瘦锹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一弯院、第九天 我趴在偏房一處隱蔽的房頂上張望辱士。 院中可真熱鬧,春花似錦听绳、人聲如沸颂碘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽头岔。三九已至,卻和暖如春鼠证,著一層夾襖步出監(jiān)牢的瞬間峡竣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工量九, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留适掰,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓荠列,卻偏偏與公主長得像类浪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肌似,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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

  • Java8張圖 11费就、字符串不變性 12、equals()方法锈嫩、hashCode()方法的區(qū)別 13受楼、...
    Miley_MOJIE閱讀 3,693評論 0 11
  • 概述 對于逃逸分析和TLAB兩種技術(shù)之間的關(guān)聯(lián)一直沒有理清楚,今天抽時間專門整理了一下這兩門技術(shù)呼寸。通過這篇文章艳汽,我...
    heyong閱讀 3,395評論 1 15
  • 逃逸分析 在計算機(jī)語言編譯器語言優(yōu)化管理中,分析指針動態(tài)范圍的方法稱之為逃逸分析对雪。 通俗點講河狐,當(dāng)一個對象的指針被多...
    光劍書架上的書閱讀 1,054評論 0 0
  • 一、運行時數(shù)據(jù)區(qū)域 Java虛擬機(jī)管理的內(nèi)存包括幾個運行時數(shù)據(jù)內(nèi)存:方法區(qū)瑟捣、虛擬機(jī)棧馋艺、本地方法棧、堆迈套、程序計數(shù)器捐祠,...
    加油小杜閱讀 1,511評論 1 15
  • 她問:“肯帶女人回去見家長的男人就是好男人了嗎踱蛀?” 我答:“十年前肯定是窿给,如今,不一定率拒”琅荩” 時移世易,很多標(biāo)準(zhǔn)早已...
    一點樂生活閱讀 1,456評論 0 0