簡述Java編程語言中的逃逸分析
大家一般認為new出來的對象都是被分配在堆上,但這并不是完全正確,通過對Java對象分配過程分析,我們發(fā)現(xiàn)對象除了可以被分配在堆上,還可以在?;騎LAB中分配空間。而棧上分配對象的技術(shù)基礎(chǔ)是逃逸分析和標量替換,本文主要介紹下逃逸分析。
1.逃逸分析的定義
逃逸分析:是一種可以有效減少Java 程序中同步負載和內(nèi)存堆分配壓力的跨函數(shù)全局數(shù)據(jù)流分析算法。
通過逃逸分析,Java Hotspot編譯器能夠分析出一個新的對象的引用的使用范圍從而決定是否要將這個對象分配到堆上。
Java在Java SE 6u23以及以后的版本中支持并默認開啟了逃逸分析的選項。Java的 HotSpot JIT編譯器,能夠在方法重載或者動態(tài)加載代碼的時候?qū)Υa進行逃逸分析。
逃逸分析的基本行為就是分析對象的動態(tài)作用域:當一個對象在方法中被定義后,它可能被外部方法所引用。
方法逃逸:例如作為調(diào)用參數(shù)傳遞到其他方法中。
線程逃逸:有可能被外部線程訪問到,譬如賦值給類變量或可以在其他線程中訪問的實例變量。
2.逃逸分析的理論基礎(chǔ)
基于 Jong-Deok Choi, Manish Gupta, Mauricio Seffano,Vugranam C. Sreedhar, Sam Midkiff等在論文《Escape Analysis for Java》中描述的算法進行逃逸分析。
該算法引入了連通圖,用連通圖來構(gòu)建對象和對象引用之間的可達性關(guān)系,并在次基礎(chǔ)上,提出一種組合數(shù)據(jù)流分析法。由于該算法是上下文相關(guān)和流敏感的,并且模擬了對象任意層次的嵌套關(guān)系,所以分析精度較高,只是運行時間和內(nèi)存消耗相對較大。
絕大多數(shù)逃逸分析的實現(xiàn)都基于“封閉世界(closed world)”的前提:所有可能被執(zhí)行的,方法在做逃逸分析前都已經(jīng)得知,并且,程序的實際運行不會改變它們之間的調(diào)用關(guān)系 。但當真實的 Java 程序運行時,這樣的假設(shè)并不成立。Java 程序擁有的許多特性,例如動態(tài)類加載、調(diào)用本地函數(shù)以及反射程序調(diào)用等等,都將打破所謂“封閉世界”的約定。
逃逸分析之后的處理操作
經(jīng)過逃逸分析之后,可以得到對象三種可能的逃逸狀態(tài):
GlobalEscape(全局逃逸): 即一個對象的引用逃出了方法或者線程。例如,一個對象的引用是復(fù)制給了一個類變量,或者存儲在在一個已經(jīng)逃逸的對象當中,或者這個對象的引用作為方法的返回值返回給了調(diào)用方法。
ArgEscape(參數(shù)級逃逸):即在方法調(diào)用過程當中傳遞對象的應(yīng)用給一個方法。這種狀態(tài)可以通過分析被調(diào)方法的二進制代碼確定。
NoEscape(沒有逃逸):一個可以進行標量替換的對象。該對象可以不被分配在傳統(tǒng)的堆上。
編譯器可以使用逃逸分析的結(jié)果,對程序進行優(yōu)化。
堆分配對象變成棧分配對象:一個方法當中的對象,對象的引用沒有發(fā)生逃逸,那么這個方法可能會被分配在棧內(nèi)存上而非常見的堆內(nèi)存上。
消除同步:線程同步的代價是相當高的,同步的后果是降低并發(fā)性和性能。逃逸分析可以判斷出某個對象是否始終只被一個線程訪問,如果只被一個線程訪問,那么對該對象的同步操作就可以轉(zhuǎn)化成沒有同步保護的操作,這樣就能大大提高并發(fā)程度和性能。
矢量替代:逃逸分析方法如果發(fā)現(xiàn)對象的內(nèi)存存儲結(jié)構(gòu)不需要連續(xù)進行的話,就可以將對象的部分甚至全部都保存在CPU寄存器內(nèi),這樣能大大提高訪問速度。
總結(jié)
以上是本文關(guān)于逃逸分析的全部內(nèi)容,希望對大家有所幫助。
相關(guān)文章
Spring?Data?JPA關(guān)系映射@OneToOne實例解析
這篇文章主要為大家介紹了Spring?Data?JPA關(guān)系映射@OneToOne實例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08org.apache.zookeeper.KeeperException.BadVersionException異常的解
在使用Apache ZooKeeper進行分布式協(xié)調(diào)時,你可能會遇到org.apache.zookeeper.KeeperException.BadVersionException異常,本文就來介紹一下解決方法,感興趣的可以了解一下2024-03-03Javaweb應(yīng)用使用限流處理大量的并發(fā)請求詳解
這篇文章主要介紹了Javaweb應(yīng)用使用限流處理大量的并發(fā)請求詳解,還是挺不錯的,這里分享給大家,供需要的朋友參考。2017-11-11SpringBoot2.6.x默認禁用循環(huán)依賴后的問題解決
由于SpringBoot從底層逐漸引導(dǎo)開發(fā)者書寫規(guī)范的代碼,同時也是個憂傷的消息,循環(huán)依賴的應(yīng)用場景實在是太廣泛了,所以SpringBoot 2.6.x不推薦使用循環(huán)依賴,本文給大家說下SpringBoot2.6.x默認禁用循環(huán)依賴后的應(yīng)對策略,感興趣的朋友一起看看吧2022-02-02Java Web學(xué)習(xí)之Cookie和Session的深入理解
這篇文章主要給大家介紹了關(guān)于Java Web學(xué)習(xí)之Cookie和Session的相關(guān)資料,需要的朋友可以參考下2018-04-04