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

JVM進(jìn)階教程之字段訪問優(yōu)化淺析

 更新時間:2019年01月07日 09:32:02   作者:機(jī)智的小鳴  
這篇文章主要給大家介紹了關(guān)于JVM進(jìn)階教程之字段訪問優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在實際中,Java程序中的對象或許 本身就是逃逸 的,或許因為 方法內(nèi)聯(lián)不夠徹底 而被即時編譯器 當(dāng)成是逃逸 的,這兩種情況都將

導(dǎo)致即時編譯器 無法進(jìn)行標(biāo)量替換 ,這時,針對對象字段訪問的優(yōu)化顯得更為重要。

static int bar(Foo o, int x) {
 o.a = x;
 return o.a;
}
  1. 對象o是傳入?yún)?shù), 不屬于逃逸分析的范圍 (JVM中的逃逸分析針對的是 新建對象 )
  2. 該方法會將所傳入的int型參數(shù)x的值存儲至實例字段Foo.a中,然后再讀取并返回同一字段的值
  3. 這段代碼涉及 兩次 內(nèi)存訪問操作:存儲和讀取實例字段Foo.a
  4. 代碼可以手工優(yōu)化成如下
static int bar(Foo o, int x) {
 o.a = x;
 return x;
}

即時編譯器也能作出類似的 自動優(yōu)化

字段讀取優(yōu)化

即時編譯器會優(yōu)化 實例字段 和 靜態(tài)字段 的訪問,以 減少總的內(nèi)存訪問次數(shù)

即時編譯器將 沿著控制流 ,緩存各個字段 存儲節(jié)點 將要存儲的值,或者字段 讀取節(jié)點 所得到的值

  • 當(dāng)即時編譯器 遇到對同一字段的讀取節(jié)點 時,如果緩存值還沒有失效,那么將讀取節(jié)點 替換 為該緩存值
  • 當(dāng)即時編譯器 遇到對同一字段的存儲節(jié)點 時,會 更新 所緩存的值
    • 當(dāng)即時編譯器遇到 可能更新 字段的節(jié)點時,它會采取 保守 的策略, 舍棄所有的緩存值
    • 方法調(diào)用節(jié)點 :在即時編譯器看來,方法調(diào)用會執(zhí)行 未知代碼
    • 內(nèi)存屏障節(jié)點 :其他線程可能異步更新了字段

樣例1

static int bar(Foo o, int x) {
 int y = o.a + x;
 return o.a + y;
}

實例字段Foo.a被讀取兩次,即時編譯器會將第一次讀取的值緩存起來,并且 替換 第二次的字段讀取操作,以 節(jié)省 一次內(nèi)存訪問

static int bar(Foo o, int x) {
 int t = o.a;
 int y = t + x;
 return t + y;
}

樣例2

static int bar(Foo o, int x) {
 o.a = 1;
 if (o.a >= 0)
  return x;
 else
  return -x;
}

字段讀取節(jié)點被替換成一個 常量 ,進(jìn)一步觸發(fā)更多的優(yōu)化

static int bar(Foo o, int x) {
 o.a = 1;
 return x;
}

樣例3

class Foo {
 boolean a;
 void bar() {
  a = true;
  while (a) {}
 }
 void whatever() { a = false; }
}

即時編譯器會將while循環(huán)中讀取實例字段a的操作 直接替換為常量true

void bar() {
 a = true;
 while (true) {}
}
// 生成的機(jī)器碼將陷入這一死循環(huán)中
0x066b: mov r11,QWORD PTR [r15+0x70] // 安全點測試
0x066f: test DWORD PTR [r11],eax  // 安全點測試
0x0672: jmp 0x066b     // while (true)

1、可以通過 volatile 關(guān)鍵字標(biāo)記實例字段a,以 強(qiáng)制 對a的讀取

2、實際上,即時編譯器將 在volatile字段訪問前后插入內(nèi)存屏障節(jié)點

  • 這些 內(nèi)存屏障節(jié)點 將 阻止 即時編譯器 將屏障之前所緩存的值用于屏障之后的讀取節(jié)點之上
  • 在X86_64平臺上,volatile字段讀取前后的內(nèi)存屏障都是no-op
    • 在 即時編譯過程中的屏障節(jié)點 ,還是會 阻止即時編譯器的字段讀取優(yōu)化
    • 強(qiáng)制在循環(huán)中使用 內(nèi)存讀取指令 訪問實例字段Foo.a的最新值

3、同理, 加解鎖操作同樣也會阻止即時編譯器的字段讀取優(yōu)化

字段存儲優(yōu)化

如果一個字段先后被存儲了兩次,而且這 兩次存儲之間沒有對第一次存儲內(nèi)容讀取 ,那么即時編譯器將 消除 第一個字段存儲

樣例1

class Foo {
 int a = 0;
 void bar() {
  a = 1;
  a = 2;
 }
}

即時編譯器將消除bar方法的冗余存儲

void bar() {
 a = 2;
}

樣例2

即便在某個字段的兩個存儲操作之間讀取該字段,即時編譯器也可能在 字段讀取優(yōu)化 的幫助下,將第一個存儲操作當(dāng)作 冗余存儲

場景:例如兩個存儲操作之間隔著許多代碼,又或者因為 方法內(nèi)聯(lián) 的原因,將兩個存儲操作納入到同一編譯單元里(如構(gòu)造器中字段的初始化以及隨后的更新)

class Foo {
 int a = 0;
 void bar() {
  a = 1;
  int t = a;
  a = t + 2;
 }
}
// 優(yōu)化為
class Foo {
 int a = 0;
 void bar() {
  a = 1;
  int t = 1;
  a = t + 2;
 }
}
// 進(jìn)一步優(yōu)化為
class Foo {
 int a = 0;
 void bar() {
  a = 3;
 }
}

如果所存儲的字段被標(biāo)記為 volatile ,那么即時編譯器也 不能消除冗余存儲

死代碼消除

樣例1

int bar(int x, int y) {
 int t = x*y;
 t = x+y;
 return t;
}

沒有節(jié)點依賴于t的第一個值 x*y ,因此該乘法運算將被消除

int bar(int x, int y) {
 return x+y;
}

樣例2

int bar(boolean f, int x, int y) {
 int t = x*y;
 if (f)
  t = x+y;
 return t;
}

部分程序路徑上有冗余存儲(f=true),該路徑上的乘法運算將會被消除

int bar(boolean f, int x, int y) {
 int t;
 if (f)
  t = x+y;
 else
  t = x*y;
 return t;
}

樣例3

int bar(int x) {
 if (false)
  return x;
 else
  return -x;
}

不可達(dá)分支指的是任何程序路徑都不可達(dá)到的分支,即時編譯器將 消除不可達(dá)分支

int bar(int x) {
 return -x;
}

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • java之CSV大批量數(shù)據(jù)入庫的實現(xiàn)

    java之CSV大批量數(shù)據(jù)入庫的實現(xiàn)

    本文主要介紹了java之CSV大批量數(shù)據(jù)入庫的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Spring如何使用@Indexed加快啟動速度

    Spring如何使用@Indexed加快啟動速度

    這篇文章主要介紹了Spring如何使用@Indexed加快啟動速度,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringBoot3.x打包Docker容器的實現(xiàn)

    SpringBoot3.x打包Docker容器的實現(xiàn)

    這篇文章主要介紹了SpringBoot3.x打包Docker容器的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • 解決cmd執(zhí)行javac報錯:不是內(nèi)部或外部命令,也不是可運行的程序

    解決cmd執(zhí)行javac報錯:不是內(nèi)部或外部命令,也不是可運行的程序

    剛接觸JAVA的新手可能就不知道怎么解決'JAVAC'不是內(nèi)部命令或外部命令,這篇文章主要給大家介紹了關(guān)于解決cmd執(zhí)行javac報錯:不是內(nèi)部或外部命令,也不是可運行的程序的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式

    使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式

    這篇文章主要介紹了使用JavaBean根據(jù)指定條件設(shè)置屬性值默認(rèn)值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java從字符串中提取數(shù)字的簡單實例

    java從字符串中提取數(shù)字的簡單實例

    下面小編就為大家?guī)硪黄猨ava從字符串中提取數(shù)字的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • Java注解Annotation與自定義注解詳解

    Java注解Annotation與自定義注解詳解

    本文全面講述了Java注解Annotation與Java自定義注解及相關(guān)內(nèi)容,大家可以認(rèn)真看看
    2018-03-03
  • Java數(shù)字圖像處理之圖像灰度處理

    Java數(shù)字圖像處理之圖像灰度處理

    這篇文章主要為大家詳細(xì)介紹了Java數(shù)字圖像處理之圖像灰度處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Spring Security 自動踢掉前一個登錄用戶的實現(xiàn)代碼

    Spring Security 自動踢掉前一個登錄用戶的實現(xiàn)代碼

    這篇文章主要介紹了Spring Security 自動踢掉前一個登錄用戶的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • Java多線程并發(fā)FutureTask使用詳解

    Java多線程并發(fā)FutureTask使用詳解

    Java?的多線程機(jī)制本質(zhì)上能夠完成兩件事情,異步計算和并發(fā),F(xiàn)utureTask?是基于?Runnable?實現(xiàn)的一個可取消的異步調(diào)用?API,本文給大家介紹Java?多線程并發(fā)FutureTask及基本使用,需要的朋友可以參考下
    2022-06-06

最新評論

贵定县| 望城县| 武强县| 扎赉特旗| 鱼台县| 叙永县| 黔江区| 加查县| 上高县| 宣城市| 盖州市| 疏勒县| 安丘市| 东乌| 宣化县| 怀宁县| 佛学| 定安县| 潞城市| 江口县| 陈巴尔虎旗| 奉节县| 朝阳县| 兰考县| 垫江县| 阿坝| 黔西| 广灵县| 鄂托克前旗| 友谊县| 许昌县| 丹江口市| 霸州市| 金湖县| 讷河市| 长泰县| 施秉县| 梁平县| 赣榆县| 湾仔区| 米林县|