国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java中的逃逸分析

jayce / 2230人閱讀

摘要:當(dāng)一個(gè)對(duì)象被定義之后,可能會(huì)被外部對(duì)象引用,稱之為方法逃逸也有可能被其他線程所引用,稱之為線程逃逸。在編譯過(guò)程中,經(jīng)過(guò)逃逸分析確定一個(gè)對(duì)象不會(huì)被其他線程或者方法訪問(wèn),那么會(huì)將對(duì)象的創(chuàng)建替換成為多個(gè)成員變量的創(chuàng)建,稱之為標(biāo)量替換。

1.引言

Java 程序運(yùn)行時(shí),JVM 會(huì)將 .class 字節(jié)碼轉(zhuǎn)換成機(jī)器能夠識(shí)別的指令,指令轉(zhuǎn)換過(guò)程會(huì)產(chǎn)生耗時(shí),延緩程序的運(yùn)行速度,為了解決這種問(wèn)題出現(xiàn)了「JIT(即時(shí)編譯)」技術(shù)。JIT 主要有兩個(gè)功能:

緩存「Hot Spot Code(熱點(diǎn)代碼:頻繁運(yùn)行的方法或代碼塊)」對(duì)應(yīng)的機(jī)器指令,方便下次調(diào)用。

代碼編譯優(yōu)化。

而在 JIT 的代碼優(yōu)化過(guò)程中,最重要的就是「逃逸分析(Escape Analysis)」。

2. 逃逸分析

逃逸分析就是 分析Java對(duì)象的動(dòng)態(tài)作用域。當(dāng)一個(gè)對(duì)象被定義之后,可能會(huì)被外部對(duì)象引用,稱之為「方法逃逸」;也有可能被其他線程所引用,稱之為「線程逃逸」。

public class EscapeObject {
    public static String createStr() {
        String sb = "hello world!";
        return sb;
    }
}

例如上面這段代碼將創(chuàng)建的字符串對(duì)象 sb 返回,這樣可以被其他方法或線程引用。

public class EscapeObject {
    public static String createStr() {
        StringBuffer sb = new StringBuffer("hello world!");
        return sb.toString();
    }
}

如果這樣實(shí)現(xiàn)的話,sb 對(duì)象就沒(méi)有「逃逸」。

利用逃逸分析,編譯器可以對(duì)代碼做如下優(yōu)化:

同步省略

標(biāo)量替換

棧上分配

2.1 同步省略

在 JIT 編譯過(guò)程中,如果發(fā)現(xiàn)一個(gè)對(duì)象不會(huì)被多線程訪問(wèn),那么針對(duì)這個(gè)對(duì)象的同步措施就可以省略掉,即「鎖銷除」。例如 Vector 和 StringBuffer 這樣的類,它們中的很多方法都是有鎖的,當(dāng)某個(gè)對(duì)象確定是線程安全的情況下,JIT編譯器會(huì)在編譯這段代碼時(shí)進(jìn)行鎖銷除來(lái)提升效率。

2.2 標(biāo)量替換

「標(biāo)量(Scalar)」是指無(wú)法再分解成更小粒度的數(shù)據(jù),例如 Java 中的原始數(shù)據(jù)類型(int,long等),相對(duì)如果一個(gè)數(shù)據(jù)可以繼續(xù)分解,則稱之為「聚合量(Aggregate)」,例如 Java對(duì)象。在 JIT 編譯過(guò)程中,經(jīng)過(guò)逃逸分析確定一個(gè)對(duì)象不會(huì)被其他線程或者方法訪問(wèn),那么會(huì)將對(duì)象的創(chuàng)建替換成為多個(gè)成員變量的創(chuàng)建,稱之為「標(biāo)量替換」。

public class EscapeObject {

    private static void getUser() {
        User user = new User("張三", 18);
        System.out.println("user name is " + user.name + ", age is " + user.age);
    }

    public static void main(String[] args) {
        getUser();
    }
}

class User {
    String name;
    int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

上面這段代碼中,對(duì)象 user 只會(huì)在getUser()方法中被調(diào)用,那么 JIT動(dòng)態(tài)編譯時(shí),不會(huì)創(chuàng)建對(duì)象 user,而之創(chuàng)建它的兩個(gè)成員變量 name 和 age,類似:

private static void getUser() {
    String name = "張三";
    int age = 18;

    System.out.println("user name is " + user.name + ", age is " + user.age);

}

public static void main(String[] args) {
    getUser();
}

標(biāo)量替換減少了創(chuàng)建對(duì)象需要的堆內(nèi)存,同時(shí)也不用進(jìn)行 GC。

2.3 棧上分配

「棧上分配」是指對(duì)象和數(shù)據(jù)不是創(chuàng)建在堆上,而是創(chuàng)建在棧上,隨著方法的結(jié)束自動(dòng)銷毀。但實(shí)際上,JVM 例如常用的「HotSpot」虛擬機(jī)并沒(méi)有實(shí)現(xiàn)棧上分配,實(shí)際是用「標(biāo)量替換」代替實(shí)現(xiàn)的。

在 JAVA 中,對(duì)象只分配在堆中:

The heap is the runtime data area from which memory for all class instances and arrays is allocated。

堆是所有的對(duì)象實(shí)例以及數(shù)組分配內(nèi)存的運(yùn)行時(shí)數(shù)據(jù)區(qū)域。
2.4 如何開(kāi)啟逃逸分析

可以通過(guò)設(shè)置 JVM 參數(shù)來(lái)開(kāi)啟或關(guān)閉逃逸分析

-XX:+DoEscapeAnalysis :開(kāi)啟逃逸分析(從JDK1.7開(kāi)始默認(rèn)開(kāi)啟)

-XX:-DoEscapeAnalysis :關(guān)閉逃逸分析

3. 參考資料

深入理解Java中的逃逸分析

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/71862.html

相關(guān)文章

  • 面試問(wèn)我 Java 逃逸分析,瞬間被秒殺了。。

    摘要:記得幾年前有一次棧長(zhǎng)去面試,問(wèn)到了這么一個(gè)問(wèn)題中的對(duì)象都是在堆中分配嗎說(shuō)明為什么當(dāng)時(shí)我被問(wèn)得一臉蒙逼,瞬間被秒殺得體無(wú)完膚,當(dāng)時(shí)我壓根就不知道他在考什么知識(shí)點(diǎn),難道對(duì)象不是在堆中分配嗎最后就沒(méi)然后了,回去等通知了。。 記得幾年前有一次棧長(zhǎng)去面試,問(wèn)到了這么一個(gè)問(wèn)題: Java中的對(duì)象都是在堆中分配嗎?說(shuō)明為什么! 當(dāng)時(shí)我被問(wèn)得一臉蒙逼,瞬間被秒殺得體無(wú)完膚,當(dāng)時(shí)我壓根就不知道他在考什么...

    CastlePeaK 評(píng)論0 收藏0
  • Java對(duì)象分配簡(jiǎn)要流程

    摘要:在一般應(yīng)用中,不會(huì)逃逸的局部對(duì)象所占的比例很大,如果能使用棧上分配,那大量的對(duì)象就會(huì)隨著方法的結(jié)束而自動(dòng)銷毀了,垃圾收集系統(tǒng)的壓力將會(huì)小很多。相關(guān)參數(shù)設(shè)置大對(duì)象直接進(jìn)入年老代的閾值,當(dāng)對(duì)象大小超過(guò)這個(gè)值時(shí),將直接在年老代分配。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card t...

    zorro 評(píng)論0 收藏0
  • JVM(1)---虛擬機(jī)在運(yùn)行期的優(yōu)化策略

    摘要:被多次執(zhí)行的循環(huán)體。數(shù)組范圍檢查消除。這種安全檢查策略可以避免溢出。不過(guò),虛擬機(jī)還是挺聰明的,它會(huì)根據(jù)運(yùn)行期收集到的信息來(lái)自動(dòng)選擇最優(yōu)方案。 1.解釋器與JIT編譯器 首先我們先來(lái)了解一下運(yùn)行在虛擬機(jī)之上的解釋器與JIT編譯器。 當(dāng)我們的虛擬機(jī)在運(yùn)行一個(gè)java程序的時(shí)候,它可以采用兩種方式來(lái)運(yùn)行這個(gè)java程序: 采用解釋器的形式,也就是說(shuō),在運(yùn)行.class運(yùn)行的時(shí)候,解釋器一邊...

    LiuZh 評(píng)論0 收藏0
  • 【JVM從小白學(xué)成大佬】2.Java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)

    摘要:虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。棧幀棧幀是用于支持虛擬機(jī)進(jìn)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu),它是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)中的虛擬機(jī)棧的棧元素。棧幀的概念結(jié)構(gòu)如下運(yùn)行時(shí)數(shù)據(jù)區(qū)腦圖高 這里我們先說(shuō)句題外話,相信大家在面試中經(jīng)常被問(wèn)到介紹Java內(nèi)存模型,我在面試別人時(shí)也會(huì)經(jīng)常問(wèn)這個(gè)問(wèn)題。但是,往往都會(huì)令我比較尷尬,我還話音未落,面試者就會(huì)背誦一段(Java虛擬...

    shuibo 評(píng)論0 收藏0
  • JVM的編譯策略

    摘要:解釋器與編譯器并存如果選用完全解釋策略,那么編譯器將停止所有的工作,字節(jié)碼將完全依靠解釋器逐行解釋執(zhí)行。如果選用完全編譯策略,那么解釋器仍然會(huì)在編譯器無(wú)法進(jìn)行的特殊情況下介入運(yùn)行,這主要是確保程序能夠最終順序執(zhí)行。 jvm系列 垃圾回收基礎(chǔ) JVM的編譯策略 GC的三大基礎(chǔ)算法 GC的三大高級(jí)算法 GC策略的評(píng)價(jià)指標(biāo) JVM信息查看 GC通用日志解讀 jvm的card table數(shù)據(jù)...

    CloudwiseAPM 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<