JVM逃逸的原理是什么

本篇文章為大家展示了JVM逃逸的原理是什么,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計制作、成都做網(wǎng)站與策劃設(shè)計,武漢網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:武漢等地區(qū)。武漢做網(wǎng)站價格咨詢:028-86922220

為什么“逃逸”

在計算機語言編譯器優(yōu)化原理中,逃逸分析是指分析指針動態(tài)范圍的方法,它同編譯器優(yōu)化原理的指針分析和外形分析相關(guān)聯(lián)。當變量(或者對象)在方法中分配后,其指針有可能被返回或者被全局引用,這樣就會被其他方法或者線程所引用,這種現(xiàn)象稱作指針(或者引用)的逃逸(Escape)。通俗點講,如果一個對象的指針被多個方法或者線程引用時,那么我們就稱這個對象的指針(或?qū)ο螅┑奶右荩‥scape)。

網(wǎng)上有位博友這么形容逃逸,用了一段簡單直接的代碼,我覺得挺直截了當?shù)?,可以供參考?/p>

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

stringBuilder是在方法的內(nèi)部變量,而此時它被直接返回,這樣stringBuilder就有可能被其他地方的方法或參數(shù)所改變,這樣它的作用域就不只是demo1了,雖然它是一個局部變量,但其發(fā)生了“逃逸”。

那么,我可以改一下代碼:

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

如此,就沒有返回StringBuilder,而是toString(),那么StringBuilder沒有從方法中直接脫離,就沒有發(fā)生逃逸。

什么是逃逸分析

逃逸分析,是一種可以有效減少Java 程序中同步負載和內(nèi)存堆分配壓力的跨函數(shù)全局數(shù)據(jù)流分析算法。通過逃逸分析,Java Hotspot編譯器能夠分析出一個新的對象的引用的使用范圍從而決定是否要將這個對象分配到堆上。 逃逸分析(Escape Analysis)算是目前Java虛擬機中比較前沿的優(yōu)化技術(shù)了。

逃逸分析的原理

Java本身的限制(對象只能分配到堆中),我可以這么理解了,為了減少臨時對象在堆內(nèi)分配的數(shù)量,我會在一個方法體內(nèi)定義一個局部變量,并且該變量在方法執(zhí)行過程中未發(fā)生逃逸,按照JVM調(diào)優(yōu)機制,首先會在堆內(nèi)存創(chuàng)建類的實例,然后將此對象的引用壓入調(diào)用棧,繼續(xù)執(zhí)行,這是JVM優(yōu)化前的方式。然后,我采用逃逸分析對JVM進行優(yōu)化。即針對棧的重新分配方式,首先找出未逃逸的變量,將該變量直接存到棧里,無需進入堆,分配完成后,繼續(xù)調(diào)用棧內(nèi)執(zhí)行,最后線程執(zhí)行結(jié)束,??臻g被回收,局部變量也被回收了。如此操作,是優(yōu)化前在堆中,優(yōu)化后在棧中,從而減少了堆中對象的分配和銷毀,從而優(yōu)化性能。

逃逸的方式

方法逃逸:在一個方法體內(nèi),定義一個局部變量,而它可能被外部方法引用,比如作為調(diào)用參數(shù)傳遞給方法,或作為對象直接返回?;蛘?,可以理解成對象跳出了方法。

線程逃逸:這個對象被其他線程訪問到,比如賦值給了實例變量,并被其他線程訪問到了。對象逃出了當前線程。

逃逸分析的好處

如果一個對象不會在方法體內(nèi),或線程內(nèi)發(fā)生逃逸(或者說是通過逃逸分析后,使其未能發(fā)生逃逸)

1. 棧上分配

一般情況下,不會逃逸的對象所占空間比較大,如果能使用棧上的空間,那么大量的對象將隨方法的結(jié)束而銷毀,減輕了GC壓力

2. 同步消除

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

3. 標量替換

Java虛擬機中的原始數(shù)據(jù)類型(int,long等數(shù)值類型以及reference類型等)都不能再進一步分解,它們可以稱為標量。相對的,如果一個數(shù)據(jù)可以繼續(xù)分解,那它稱為聚合量,Java中最典型的聚合量是對象。如果逃逸分析證明一個對象不會被外部訪問,并且這個對象是可分解的,那程序真正執(zhí)行的時候?qū)⒖赡懿粍?chuàng)建這個對象,而改為直接創(chuàng)建它的若干個被這個方法使用到的成員變量來代替。拆散后的變量便可以被單獨分析與優(yōu)化,可以各自分別在棧幀或寄存器上分配空間,原本的對象就無需整體分配空間了。

開啟設(shè)置

在JDK 6u23以上是默認開啟,這里將設(shè)置重新明確一下:

強制開啟:

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

關(guān)閉逃逸分析:

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

上述內(nèi)容就是JVM逃逸的原理是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享文章:JVM逃逸的原理是什么
文章URL:http://muchs.cn/article30/ghgdso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、商城網(wǎng)站App設(shè)計、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)