轉(zhuǎn)自:JVM優(yōu)化之逃逸分析(Escape Analysis)
什么是逃逸分析(Escape Analysis)?
在編程語言的編譯優(yōu)化原理中,分析指針動態(tài)范圍的方法稱之為逃逸分析。它跟靜態(tài)代碼分析技術(shù)中的指針分析和外形分析類似。
通俗一點講,當(dāng)一個對象的指針被多個方法或線程引用時,我們稱這個指針發(fā)生了逃逸。而用來分析這種逃逸現(xiàn)象的方法,就稱之為逃逸分析。
舉個例子:
在這個例子中,一共舉了3種常見的指針逃逸場景。分別是 全局變量賦值,方法返回值,實例引用傳遞。
逃逸分析優(yōu)化JVM原理
我們知道java對象是在堆里分配的,在調(diào)用棧中,只保存了對象的指針。
當(dāng)對象不再使用后,需要依靠GC來遍歷引用樹并回收內(nèi)存,如果對象數(shù)量較多,將給GC帶來較大壓力,也間接影響了應(yīng)用的性能。減少臨時對象在堆內(nèi)分配的數(shù)量,無疑是最有效的優(yōu)化方法。
怎么減少臨時對象在堆內(nèi)的分配數(shù)量呢?不可能不實例化對象吧!
場景介紹
其實,在java應(yīng)用里普遍存在一種場景。一般是在方法體內(nèi),聲明了一個局部變量,且該變量在方法執(zhí)行生命周期內(nèi)未發(fā)生逃逸(在方法體內(nèi),未將引用暴露給外面)。
按照JVM內(nèi)存分配機制,首先會在堆里創(chuàng)建變量類的實例,然后將返回的對象指針壓入調(diào)用棧,繼續(xù)執(zhí)行。
這是優(yōu)化前,JVM的處理方式。
逃逸分析優(yōu)化 - 棧上分配
優(yōu)化原理:分析找到未逃逸的變量,將變量類的實例化內(nèi)存直接在棧里分配(無需進(jìn)入堆),分配完成后,繼續(xù)在調(diào)用棧內(nèi)執(zhí)行,最后線程結(jié)束,??臻g被回收,局部變量對象也被回收。
這是優(yōu)化后的處理方式,對比可以看出,主要區(qū)別在棧空間直接作為臨時對象的存儲介質(zhì)。從而減少了臨時對象在堆內(nèi)的分配數(shù)量。
逃逸分析的原理很簡單,但JVM在應(yīng)用過程中,還是有諸多考慮。
比如,逃逸分析不能在靜態(tài)編譯時進(jìn)行,必須在JIT里完成。原因是,與java的動態(tài)性有沖突。因為你可以在運行時,通過動態(tài)代理改變一個類的行為,此時,逃逸分析是無法得知類已經(jīng)變化了。
逃逸分析另一個重要的優(yōu)化 - 同步消除
如果你定義的類的方法上有同步鎖,但在運行時,卻只有一個線程在訪問,此時逃逸分析后的機器碼,會去掉同步鎖運行。
來自 http://blog.uncommons.org/ 性能測試結(jié)果。
測試場景1:
生成幾百萬個隨機數(shù),然后做一些少量運算。
VM 參數(shù): -server
95 秒
VM 參數(shù): -server -XX:+DoEscapeAnalysis
73 秒
性能提高: 23%
測試場景2:
非負(fù)矩陣分解算法。
VM 參數(shù): -server
22.6 秒
VM 參數(shù): -server -XX:+DoEscapeAnalysis
20.8 秒
性能提升: 8%
安裝jdk1.6.0_14,運行java時傳遞jvm參數(shù) -XX:+DoEscapeAnalysis
逃逸分析還能用于以下優(yōu)化場景,但在JVM中未知使用。
1,標(biāo)量替換(Scalar Replacement)
2,減小競爭檢測范圍
3,基于區(qū)域的內(nèi)存分配
…...
參考資料:
http://www.cag.csail.mit.edu/~rinard/pointer_and_escape_analysis/
http://developer.amd.com/documentation/Articles/pages/01302008_jvm.aspx
http://en.wikipedia.org/wiki/Escape_analysis
http://en.wikipedia.org/wiki/Java_performance#Escape_analysis_and_lock_coarsening
http://staff.ustc.edu.cn/~yuzhang/papers/cncc07.pdf (一種實現(xiàn)方法,過于學(xué)術(shù),不過引言部分寫得很不錯)
http://java.dzone.com/articles/escape-analysis-java-6-update
http://en.wikipedia.org/wiki/Non-negative_matrix_factorization