亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

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

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

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

字段讀取優(yōu)化

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

即時(shí)編譯器將 沿著控制流 ,緩存各個(gè)字段 存儲(chǔ)節(jié)點(diǎn) 將要存儲(chǔ)的值,或者字段 讀取節(jié)點(diǎn) 所得到的值

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

樣例1

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

實(shí)例字段Foo.a被讀取兩次,即時(shí)編譯器會(huì)將第一次讀取的值緩存起來,并且 替換 第二次的字段讀取操作,以 節(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é)點(diǎn)被替換成一個(gè) 常量 ,進(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; }
}

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

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

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

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

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

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

字段存儲(chǔ)優(yōu)化

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

樣例1

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

即時(shí)編譯器將消除bar方法的冗余存儲(chǔ)

void bar() {
 a = 2;
}

樣例2

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

場景:例如兩個(gè)存儲(chǔ)操作之間隔著許多代碼,又或者因?yàn)?方法內(nèi)聯(lián) 的原因,將兩個(gè)存儲(chǔ)操作納入到同一編譯單元里(如構(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;
 }
}

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

死代碼消除

樣例1

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

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

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;
}

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

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á)到的分支,即時(shí)編譯器將 消除不可達(dá)分支

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

總結(jié)

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

相關(guān)文章

  • springboot中的springSession的存儲(chǔ)和獲取實(shí)現(xiàn)

    springboot中的springSession的存儲(chǔ)和獲取實(shí)現(xiàn)

    這篇文章主要介紹了springboot中的springSession的存儲(chǔ)和獲取實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • 實(shí)例講解Java的Spring框架中的AOP實(shí)現(xiàn)

    實(shí)例講解Java的Spring框架中的AOP實(shí)現(xiàn)

    這篇文章主要介紹了Java的Spring框架中的AOP實(shí)現(xiàn)實(shí)例,AOP面向切面編程其實(shí)也可以被看作是一個(gè)設(shè)計(jì)模式去規(guī)范項(xiàng)目的結(jié)構(gòu),需要的朋友可以參考下
    2016-04-04
  • Java遞歸實(shí)現(xiàn)字符串全排列與全組合

    Java遞歸實(shí)現(xiàn)字符串全排列與全組合

    這篇文章主要為大家詳細(xì)介紹了Java遞歸實(shí)現(xiàn)字符串全排列與全組合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • 如何解決springboot讀取配置文件的中文亂碼問題

    如何解決springboot讀取配置文件的中文亂碼問題

    本篇文章主要介紹了如何解決springboot讀取配置文件的中文亂碼問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看
    2018-05-05
  • Spring?Boot?整合?Fisco?Bcos部署、調(diào)用區(qū)塊鏈合約的案例

    Spring?Boot?整合?Fisco?Bcos部署、調(diào)用區(qū)塊鏈合約的案例

    本篇文章介紹?Spring?Boot?整合?Fisco?Bcos?的相關(guān)技術(shù),最最重要的技術(shù)點(diǎn),部署、調(diào)用區(qū)塊鏈合約的工程案例,本文通過流程分析給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-01-01
  • java隨機(jī)數(shù)生成具體實(shí)現(xiàn)代碼

    java隨機(jī)數(shù)生成具體實(shí)現(xiàn)代碼

    這篇文章主要為大家分享了java隨機(jī)數(shù)生成具體實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Java實(shí)現(xiàn)冒泡排序算法

    Java實(shí)現(xiàn)冒泡排序算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)冒泡排序算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Springboot 使用 JSR 303 對(duì) Controller 控制層校驗(yàn)及 Service 服務(wù)層 AOP 校驗(yàn) 使用消息資源文件對(duì)消息國際化

    Springboot 使用 JSR 303 對(duì) Controller 控制層校驗(yàn)及 Service 服務(wù)層 AOP 校驗(yàn)

    這篇文章主要介紹了Springboot 使用 JSR 303 對(duì) Controller 控制層校驗(yàn)及 Service 服務(wù)層 AOP 校驗(yàn) 使用消息資源文件對(duì)消息國際化的相關(guān)知識(shí),需要的朋友可以參考下
    2017-12-12
  • JVM處理未捕獲異常的方法詳解

    JVM處理未捕獲異常的方法詳解

    這篇文章主要給大家介紹了關(guān)于JVM處理未捕獲異常的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 通過工廠模式返回Spring Bean方法解析

    通過工廠模式返回Spring Bean方法解析

    這篇文章主要介紹了通過工廠模式返回Spring Bean方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論