搜尋
首頁Javajava教程JVM的逃逸是什麼? JVM逃逸分析的原理介紹

這篇文章帶給大家的內容是關於JVM的逃逸是什麼? JVM逃逸分析的原理介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

我們都知道Java中的物件預設都是分配到堆疊上,在呼叫堆疊中,只保存了物件的指標。當物件不再使用後,需要依靠GC來遍歷引用樹並回收記憶體。如果堆中物件數量太多,回收物件還有整理內存,都會帶來時間上的消耗,GC表示壓力很大,然後影響效能。所以,在我們日常開發中,內存,時間都是相當的寶貴,該如何優化堆疊開銷,是一個比較重要的問題。

在這裡,我以逃逸分析角度聊聊JVM優化的事。

為什麼「逃逸

在電腦語言編譯器最佳化原理中,逃逸分析是指分析指標動態範圍的方法,它同編譯器最佳化原理的指標分析和外形分析相關聯。當變數(或物件)在方法中被指派後,其指標有可能被傳回或被全域引用,這樣就會被其他方法或執行緒所引用,這種現象稱作指標(或引用)的逃逸(Escape)。通俗點講,如果一個物件的指標被多個方法或線程引用時,那麼我們就稱這個物件的指標(或物件)的逃逸(Escape)。

網路上有位博友這麼形容逃逸,用了一段簡單直接的程式碼,我覺得挺直截了當的,可以供參考:

public StringBuilder escapeDemo1(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder;
}

stringBuilder是在方法的內部變量,而此時它被直接傳回,這樣stringBuilder就有可能被其他地方的方法或參數所改變,這樣它的作用域就不只是demo1了,雖然它是一個局部變量,但其發生了「逃逸」。

那麼,我可以改一下程式碼:

public String escapeDemo2(System a, System b) {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(a);
    stringBuilder.append(b);
    return stringBuilder.toString();
}

如此,就沒有回傳StringBuilder,而是toString(),那麼StringBuilder沒有從方法直接脫離,就沒有發生逃逸。

什麼是逃逸分析

逃逸分析,是一種可以有效減少Java 程式中同步負載和記憶體堆分配壓力的跨函數全域資料流分析演算法。透過逃逸分析,Java Hotspot編譯器能夠分析出一個新的物件的引用的使用範圍從而決定是否要將這個物件指派到堆上。 逃逸分析(Escape Analysis)算是目前Java虛擬機器中比較前​​沿的最佳化技術了。

逃逸分析的原理

Java本身的限制(物件只能被分配到堆中),我可以這麼理解了,為了減少臨時物件在堆內分配的數量,我會在一個方法體內定義一個局部變量,並且該變量在方法執行過程中未發生逃逸,按照JVM調優機制,首先會在堆內存創建類的實例,然後將此對象的引用壓入呼叫棧,繼續執行,這是JVM優化前的方式。然後,我採用逃逸分析對JVM進行最佳化。即針對棧的重新分配方式,首先找出未逃逸的變量,將該變量直接存到棧裡,無需進入堆,分配完成後,繼續調用棧內執行,最後線程執行結束,棧空間被回收,局部變數也被回收了。如此操作,是優化前在堆中,優化後在堆疊中,從而減少了堆中物件的分配和銷毀,從而優化效能。

逃逸的方式

方法逃逸:在一個方法體內,定義一個局部變量,而它可能被外部方法引用,例如作為呼叫參數傳遞給方法,或作為對象直接回傳。或者,可以理解成物件跳出了方法。

執行緒逃逸:這個物件被其他執行緒存取到,例如賦值給了實例變量,並被其他執行緒存取到了。物件逃出了當前線程。

逃逸分析的好處

如果一個物件不會在方法體內,或執行緒內發生逃逸(或者說是透過逃逸分析後,使其未能發生逃逸)

1. 堆疊上分配

一般情況下,不會逃逸的物件所佔空間比較大,如果能使用堆疊上的空間,那麼大量的物件將隨方法的結束而銷毀,減輕了GC壓力

2. 同步消除

如果你定義的類別的方法上有同步鎖,但在運行時,卻只有一個執行緒在訪問,此時逃逸分析後的機器碼,會去掉同步鎖定運作。

3. 標量替換

Java虚拟机中的原始数据类型(int,long等数值类型以及reference类型等)都不能再进一步分解,它们可以称为标量。相对的,如果一个数据可以继续分解,那它称为聚合量,Java中最典型的聚合量是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个对象是可分解的,那程序真正执行的时候将可能不创建这个对象,而改为直接创建它的若干个被这个方法使用到的成员变量来代替。拆散后的变量便可以被单独分析与优化,可以各自分别在栈帧或寄存器上分配空间,原本的对象就无需整体分配空间了。

开启设置

在JDK 6u23以上是默认开启,这里将设置重新明确一下:
强制开启:   

 -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

关闭逃逸分析:    

-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

写在结尾

栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,无法存储大容量数据。目前的实现都是采用不那么准确但是时间压力相对较小的算法来完成逃逸分析,这就可能导致效果不稳定。所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的小容量的变量分配结构,才是合适的。

以上是JVM的逃逸是什麼? JVM逃逸分析的原理介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除
說明JVM如何充當Java代碼和基礎操作系統之間的中介。說明JVM如何充當Java代碼和基礎操作系統之間的中介。Apr 29, 2025 am 12:23 AM

JVM的工作原理是將Java代碼轉換為機器碼並管理資源。 1)類加載:加載.class文件到內存。 2)運行時數據區:管理內存區域。 3)執行引擎:解釋或編譯執行字節碼。 4)本地方法接口:通過JNI與操作系統交互。

解釋Java虛擬機(JVM)在Java平台獨立性中的作用。解釋Java虛擬機(JVM)在Java平台獨立性中的作用。Apr 29, 2025 am 12:21 AM

JVM使Java實現跨平台運行。 1)JVM加載、驗證和執行字節碼。 2)JVM的工作包括類加載、字節碼驗證、解釋執行和內存管理。 3)JVM支持高級功能如動態類加載和反射。

您將採取哪些步驟來確保Java應用程序在不同的操作系統上正確運行?您將採取哪些步驟來確保Java應用程序在不同的操作系統上正確運行?Apr 29, 2025 am 12:11 AM

Java應用可通過以下步驟在不同操作系統上運行:1)使用File或Paths類處理文件路徑;2)通過System.getenv()設置和獲取環境變量;3)利用Maven或Gradle管理依賴並測試。 Java的跨平台能力依賴於JVM的抽象層,但仍需手動處理某些操作系統特定的功能。

Java是否需要特定於平台的配置或調整區域?Java是否需要特定於平台的配置或調整區域?Apr 29, 2025 am 12:11 AM

Java在不同平台上需要進行特定配置和調優。 1)調整JVM參數,如-Xms和-Xmx設置堆大小。 2)選擇合適的垃圾回收策略,如ParallelGC或G1GC。 3)配置Native庫以適應不同平台,這些措施能讓Java應用在各種環境中發揮最佳性能。

哪些工具或庫可以幫助您解決Java開發中特定於平台的挑戰?哪些工具或庫可以幫助您解決Java開發中特定於平台的挑戰?Apr 29, 2025 am 12:01 AM

Osgi,Apachecommonslang,JNA和JvMoptionsareeForhandlingForhandlingPlatform-specificchallengesinjava.1)osgimanagesdeppedendendencenciesandisolatescomponents.2)apachecommonslangprovidesitorityfunctions.3)

JVM如何在不同平台上管理垃圾收集?JVM如何在不同平台上管理垃圾收集?Apr 28, 2025 am 12:23 AM

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

為什麼Java代碼可以在不同的操作系統上運行,而無需修改?為什麼Java代碼可以在不同的操作系統上運行,而無需修改?Apr 28, 2025 am 12:14 AM

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

描述編譯和執行Java程序的過程,突出平台獨立性。描述編譯和執行Java程序的過程,突出平台獨立性。Apr 28, 2025 am 12:08 AM

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),