最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java逃逸分析詳解及代碼示例

 更新時間:2017年11月10日 10:33:19   作者:StormMa  
這篇文章主要介紹了Java逃逸分析詳解及代碼示例,具有一定參考價值,需要的朋友可以了解下。

概念引入

我們都知道,Java 創(chuàng)建的對象都是被分配到堆內(nèi)存上,但是事實(shí)并不是這么絕對,通過對Java對象分配的過程分析,可以知道有兩個地方會導(dǎo)致Java中創(chuàng)建出來的對象并一定分別在所認(rèn)為的堆上。這兩個點(diǎn)分別是Java中的逃逸分析和TLAB(Thread Local Allocation Buffer)線程私有的緩存區(qū)。

基本概念介紹

逃逸分析,是一種可以有效減少Java程序中同步負(fù)載和內(nèi)存堆分配壓力的跨函數(shù)全局?jǐn)?shù)據(jù)流分析算法。通過逃逸分析,Java Hotspot編譯器能夠分析出一個新的對象的引用的使用范圍從而決定是否要將這個對象分配到堆上。

在計算機(jī)語言編譯器優(yōu)化原理中,逃逸分析是指分析指針動態(tài)范圍的方法,它同編譯器優(yōu)化原理的指針分析和外形分析相關(guān)聯(lián)。當(dāng)變量(或者對象)在方法中分配后,其指針有可能被返回或者被全局引用,這樣就會被其他過程或者線程所引用,這種現(xiàn)象稱作指針(或者引用)的逃逸(Escape)。通俗點(diǎn)講,如果一個對象的指針被多個方法或者線程引用時,那么我們就稱這個對象的指針發(fā)生了逃逸。

Java在Java SE 6u23以及以后的版本中支持并默認(rèn)開啟了逃逸分析的選項(xiàng)。Java的 HotSpot JIT編譯器,能夠在方法重載或者動態(tài)加載代碼的時候?qū)Υa進(jìn)行逃逸分析,同時Java對象在堆上分配和內(nèi)置線程的特點(diǎn)使得逃逸分析成Java的重要功能。

代碼示例

package me.stormma.gc;
/**
 * <p>Created on 2017/4/21.</p>
 *
 * @author stormma
 *
 * @title <p>逃逸分析</p>
 */
public class EscapeAnalysis {
  public static B b;
  /**
   * <p>全局變量賦值發(fā)生指針逃逸</p>
   */
  public void globalVariablePointerEscape() {
    b = new B();
  }
  /**
   * <p>方法返回引用,發(fā)生指針逃逸</p>
   * @return
   */
  public B methodPointerEscape() {
    return new B();
  }
  /**
   * <p>實(shí)例引用發(fā)生指針逃逸</p>
   */
  public void instancePassPointerEscape() {
    methodPointerEscape().printClassName(this);
  }
  class B {
    public void printClassName(EscapeAnalysis clazz) {
      System.out.println(clazz.getClass().getName());
    }
  }
}

逃逸分析研究對于 java 編譯器有什么好處呢?我們知道 java 對象總是在堆中被分配的,因此 java 對象的創(chuàng)建和回收對系統(tǒng)的開銷是很大的。java 語言被批評的一個地方,也是認(rèn)為 java 性能慢的一個原因就是 java不支持棧上分配對象。JDK6里的 Swing內(nèi)存和性能消耗的瓶頸就是由于 GC 來遍歷引用樹并回收內(nèi)存的,如果對象的數(shù)目比較多,將給 GC 帶來較大的壓力,也間接得影響了性能。減少臨時對象在堆內(nèi)分配的數(shù)量,無疑是最有效的優(yōu)化方法。java 中應(yīng)用里普遍存在一種場景,一般是在方法體內(nèi),聲明了一個局部變量,并且該變量在方法執(zhí)行生命周期內(nèi)未發(fā)生逃逸,按照 JVM內(nèi)存分配機(jī)制,首先會在堆內(nèi)存上創(chuàng)建類的實(shí)例(對象),然后將此對象的引用壓入調(diào)用棧,繼續(xù)執(zhí)行,這是 JVM優(yōu)化前的方式。當(dāng)然,我們可以采用逃逸分析對 JVM 進(jìn)行優(yōu)化。即針對棧的重新分配方式,首先我們需要分析并且找到未逃逸的變量,將該變量類的實(shí)例化內(nèi)存直接在棧里分配,無需進(jìn)入堆,分配完成之后,繼續(xù)調(diào)用棧內(nèi)執(zhí)行,最后線程執(zhí)行結(jié)束,??臻g被回收,局部變量對象也被回收,通過這種方式的優(yōu)化,與優(yōu)化前的方案主要區(qū)別在于對象的存儲介質(zhì),優(yōu)化前是在堆中,而優(yōu)化后的是在棧中,從而減少了堆中臨時對象的分配(較耗時),從而優(yōu)化性能。

使用逃逸分析進(jìn)行性能優(yōu)化(-XX:+DoEscapeAnalysis開啟逃逸分析)

public void method() {
  Test test = new Test();
  //處理邏輯
  ......
  test = null;
}

這段代碼,之所以可以在棧上進(jìn)行內(nèi)存分配,是因?yàn)闆]有發(fā)生指針逃逸,即是引用沒有暴露出這個方法體。

棧和堆內(nèi)存分配比較

package me.stormma.gc;
/**
 * <p>Created on 2017/4/21.</p>
 *
 * @author stormma
 * @description: <p>內(nèi)存分配比較</p>
 */
public class EscapeAnalysisTest {
  public static void alloc() {
    byte[] b = new byte[2];
    b[0] = 1;
  }
  public static void main(String[] args) {
    long b = System.currentTimeMillis();
    for (int i = 0; i < 100000000; i++) {
      alloc();
    }
    long e = System.currentTimeMillis();
    System.out.println(e - b);
  }
}

JVM 參數(shù)為-server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC, 運(yùn)行結(jié)果

JVM 參數(shù)為-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC, 運(yùn)行結(jié)果

性能測試

package me.stormma.gc;
/**
 * <p>Created on 2017/4/21.</p>
 *
 * @author stormma
 *
 * @description: <p>利用逃逸分析進(jìn)行性能優(yōu)化</p>
 */
public class EscapeAnalysisTest {
  private static class Foo {
    private int x;
    private static int counter;
    public Foo() {
      x = (++counter);
    }
  }
  public static void main(String[] args) {
    long start = System.nanoTime();
    for (int i = 0; i < 1000 * 1000 * 10; ++i) {
      Foo foo = new Foo();
    }
    long end = System.nanoTime();
    System.out.println("Time cost is " + (end - start));
  }
}

使用逃逸分析優(yōu)化 JVM輸出結(jié)果( -server -XX:+DoEscapeAnalysis -XX:+PrintGC)

Time cost is 11012345

未使用逃逸分析優(yōu)化 JVM 輸出結(jié)果( -server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC)

[GC (Allocation Failure) 33280K->408K(125952K), 0.0010344 secs]
[GC (Allocation Failure) 33688K->424K(125952K), 0.0009799 secs]
[GC (Allocation Failure) 33704K->376K(125952K), 0.0007297 secs]
[GC (Allocation Failure) 33656K->456K(159232K), 0.0014817 secs]
Time cost is 68562263

分析結(jié)果,性能優(yōu)化1/6。

總結(jié)

以上就是本文關(guān)于Java逃逸分析詳解及代碼示例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Java實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題與讀者寫者問題詳解java算法實(shí)現(xiàn)紅黑樹完整代碼示例、Java編程接口調(diào)用的作用及代碼分享等,有什么問題可以隨時留言,小編會及時回復(fù)大家的。感謝朋友們對本站的支持。

相關(guān)文章

  • 在JPA中criteriabuilder使用or拼接多個like語句

    在JPA中criteriabuilder使用or拼接多個like語句

    這篇文章主要介紹了在JPA中criteriabuilder使用or拼接多個like語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • MySqlConnector的使用教程

    MySqlConnector的使用教程

    本文詳細(xì)介紹了MySqlConnector的核心功能,包括數(shù)據(jù)變更捕獲、KafkaConnect兼容性、配置管理、版本信息、連接器任務(wù)創(chuàng)建、配置驗(yàn)證、數(shù)據(jù)庫連接建立和連接器配置創(chuàng)建等,感興趣的可以了解一下
    2024-10-10
  • SpringBoot后端解決跨域問題的3種方案分享

    SpringBoot后端解決跨域問題的3種方案分享

    這篇文章主要給大家分享介紹了關(guān)于SpringBoot后端解決跨域問題的3種方案,跨域指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制,需要的朋友可以參考下
    2023-07-07
  • Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例

    Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例

    這篇文章主要介紹了Spring boot2.x中集成H2數(shù)據(jù)庫代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • java遍歷http請求request的所有參數(shù)實(shí)現(xiàn)方法

    java遍歷http請求request的所有參數(shù)實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄猨ava遍歷http請求request的所有參數(shù)實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • 淺談Java 繼承接口同名函數(shù)問題

    淺談Java 繼承接口同名函數(shù)問題

    這篇文章主要介紹了淺談Java 繼承接口同名函數(shù)問題。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • springSecurity之如何添加自定義過濾器

    springSecurity之如何添加自定義過濾器

    這篇文章主要介紹了springSecurity之如何添加自定義過濾器的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • springboot如何使用sm2加密傳輸

    springboot如何使用sm2加密傳輸

    這篇文章主要介紹了springboot如何使用sm2加密傳輸問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java 8 對 HashSet 元素進(jìn)行排序的操作方法

    Java 8 對 HashSet 元素進(jìn)行排序的操作方法

    Java 中HashSet是一個不保證元素順序的集合類,其內(nèi)部是基于 HashMap 實(shí)現(xiàn)的,HashSet不支持排序,我們在需要對HashSet 排序時,必須將其轉(zhuǎn)換為支持排序的集合或數(shù)據(jù)結(jié)構(gòu),如 List,本文將詳細(xì)介紹在 Java 8 中如何對 HashSet 中的元素進(jìn)行排序,感興趣的朋友一起看看吧
    2024-11-11
  • mybatis自動生成@Table、@Column、@Id注解的方法

    mybatis自動生成@Table、@Column、@Id注解的方法

    這篇文章主要介紹了mybatis自動生成@Table、@Column、@Id注解的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12

最新評論

增城市| 双城市| 昂仁县| 进贤县| 西乡县| 阜平县| 虎林市| 修水县| 延寿县| 玉树县| 噶尔县| 文登市| 大城县| 凉城县| 绥阳县| 滕州市| 邓州市| 东乌珠穆沁旗| 寿光市| 甘泉县| 盐源县| 九江市| 平塘县| 即墨市| 连南| 盐津县| 梅河口市| 临泽县| 信阳市| 外汇| 龙井市| 阳泉市| 闽清县| 平塘县| 牟定县| 岚皋县| 新源县| 白山市| 蛟河市| 高邮市| 中山市|