淺談JVM系列之從匯編角度分析NullCheck
一個(gè)普通的virtual call
我們來(lái)分析一下在方法中調(diào)用list.add方法的例子:
public class TestNull { public static void main(String[] args) throws InterruptedException { List<String> list= new ArrayList(); list.add("www.flydean.com"); for (int i = 0; i < 10000; i++) { testMethod(list); } Thread.sleep(1000); } private static void testMethod(List<String> list) { list.get(0); } }
代碼很簡(jiǎn)單,我們?cè)谘h(huán)中調(diào)用testMethod方法,而這個(gè)方法里面又調(diào)用了list.get(0)方法,來(lái)獲取list的第一個(gè)參數(shù)。
單純的看testMethod,這個(gè)方法是有可能拋出NullPointerException的,但是從整體運(yùn)行的角度來(lái)看,因?yàn)槲覀兊膌ist是有值的, 所以不會(huì)拋出異常。
使用JIT Watcher看看運(yùn)行結(jié)果:
先看第二個(gè)和第三個(gè)紅框,我們可以看到代碼先做了參數(shù)類型的比較,然后對(duì)testMethod進(jìn)行了優(yōu)化,這里還可以看到get方法是內(nèi)聯(lián)到testMethod中的。
代碼優(yōu)化的部分我們找到了,那么異常處理呢?如果list為空,應(yīng)該怎么處理異常呢?
第一個(gè)紅框,大家可以看到是一個(gè)隱式的異常處理,它重定向到1152b4f01這個(gè)地址。
第四個(gè)紅框就是這地址,表示的是異常處理的代碼。
普通方法中的null check
我們?cè)谏厦娴钠胀ǚ椒ɡ锩婕由弦粋€(gè)null check:
public class TestNull1 { public static void main(String[] args) throws InterruptedException { List<String> list= new ArrayList(); list.add("www.flydean.com"); for (int i = 0; i < 10000; i++) { testMethod(list); } Thread.sleep(1000); } private static void testMethod(List<String> list) { if(list !=null ){ list.get(0); } } }
上面我們添加了一個(gè)list !=null的判斷。
運(yùn)行看下結(jié)果:
相比較而言,我們可以看到,代碼其實(shí)沒(méi)有太多的變化,說(shuō)明JIT在代碼優(yōu)化的過(guò)程中,將null check優(yōu)化掉了。
那么null check到底在什么地方呢? 看我標(biāo)紅的第二個(gè)框,這里是之前的異常處理區(qū)域,我們可以看到里面有一個(gè)ifnull,表明這里做了null check。
反優(yōu)化的例子
上面的兩個(gè)例子,我們可以看出在virtual method中,JIT對(duì)null check進(jìn)行了優(yōu)化。接下來(lái)我們?cè)倏匆粋€(gè)例子,在這個(gè)例子中,我們顯示的傳遞一個(gè)null給testMethod,然后再次循環(huán)testMethod,如下所示。
for (int i = 0; i < 10000; i++) { testMethod(list); } Thread.sleep(1000); testMethod(null); for (int i = 0; i < 10000; i++) { testMethod(list); }
我們看下JIT的結(jié)果:
看下結(jié)果有什么不同呢?
第一,ifnull現(xiàn)在是顯示調(diào)用的,并不包含在隱式異常中。
第二,隱式異常也不見(jiàn)了,因?yàn)槭褂蔑@示的ifnull。
以上就是淺談JVM系列之從匯編角度分析NullCheck的詳細(xì)內(nèi)容,更多關(guān)于JVM系列之從匯編角度分析NullCheck的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
seata-1.4.0安裝及在springcloud中使用詳解
這篇文章主要介紹了seata-1.4.0安裝及在springcloud中使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12SpringSecurity+OAuth2.0?搭建認(rèn)證中心和資源服務(wù)中心流程分析
OAuth?2.0?主要用于在互聯(lián)網(wǎng)上安全地委托授權(quán),廣泛應(yīng)用于身份驗(yàn)證和授權(quán)場(chǎng)景,這篇文章介紹SpringSecurity+OAuth2.0?搭建認(rèn)證中心和資源服務(wù)中心,感興趣的朋友一起看看吧2024-01-01淺入淺出的講解Spring循環(huán)依賴問(wèn)題
循環(huán)依賴其實(shí)就是循環(huán)引用,也就是兩個(gè)或則兩個(gè)以上的bean互相持有對(duì)方,最終形成閉環(huán),下面這篇文章主要給大家介紹了關(guān)于Spring循環(huán)依賴問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-10-10在navicat中導(dǎo)入mysql數(shù)據(jù)庫(kù)詳細(xì)步驟(即.sql后綴的數(shù)據(jù)庫(kù))
Navicat是MySQL非常好用的可視化管理工具,功能非常強(qiáng)大,能滿足我們?nèi)粘?shù)據(jù)庫(kù)開發(fā)的所有需求,下面這篇文章主要給大家介紹了關(guān)于如何在navicat中導(dǎo)入mysql數(shù)據(jù)庫(kù)(即.sql后綴的數(shù)據(jù)庫(kù))的相關(guān)資料,需要的朋友可以參考下2023-04-04SpringBoot集成WebSocket遇到的問(wèn)題及解決
這篇文章主要介紹了SpringBoot集成WebSocket遇到的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-07-07java同步器AQS架構(gòu)AbstractQueuedSynchronizer原理解析下
這篇文章主要為大家介紹了java同步器AQS架構(gòu)AbstractQueuedSynchronizer原理解析下,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03