這個(gè)優(yōu)化方法比較易懂,就是對于僅在方法內(nèi)部用到的對象,不再分配在堆上,而是直接在棧上分配,方法結(jié)束后立即回收,這將大大減輕GC的壓力。
其實(shí),這個(gè)優(yōu)化方法就是java里的逃逸分析,不知為何.net里沒有引入。
英文討論貼:https://github.com/dotnet/coreclr/issues/1784
附注:逃逸分析優(yōu)化JVM原理(轉(zhuǎn)自http://f.dataguru.cn/thread-346269-1-1.html)
我們知道java對象是在堆里分配的,在調(diào)用棧中,只保存了對象的指針。
當(dāng)對象不再使用后,需要依靠GC來遍歷引用樹并回收內(nèi)存,如果對象數(shù)量較多,將給GC帶來較大壓力,也間接影響了應(yīng)用的性能。減少臨時(shí)對象在堆內(nèi)分配的數(shù)量,無疑是最有效的優(yōu)化方法。
接下來,舉一個(gè)場景來闡述。
假設(shè)在方法體內(nèi),聲明了一個(gè)局部變量,且該變量在方法執(zhí)行生命周期內(nèi)未發(fā)生逃逸(在方法體內(nèi),未將引用暴露給外面)。
按照J(rèn)VM內(nèi)存分配機(jī)制,首先會(huì)在堆里創(chuàng)建變量類的實(shí)例,然后將返回的對象指針壓入調(diào)用棧,繼續(xù)執(zhí)行。
這是優(yōu)化前,JVM的處理方式。
逃逸分析優(yōu)化 – 棧上分配
優(yōu)化原理:分析找到未逃逸的變量,將變量類的實(shí)例化內(nèi)存直接在棧里分配(無需進(jìn)入堆),分配完成后,繼續(xù)在調(diào)用棧內(nèi)執(zhí)行,最后線程結(jié)束,棧空間被回收,局部變量也被回收。
這是優(yōu)化后的處理方式,對比可以看出,主要區(qū)別在??臻g直接作為臨時(shí)對象的存儲(chǔ)介質(zhì)。從而減少了臨時(shí)對象在堆內(nèi)的分配數(shù)量。
逃逸分析另一個(gè)重要的優(yōu)化 – 鎖省略
如果通過逃逸分析能夠判斷出指向某個(gè)局部變量的多個(gè)引用被限制在同一方法體內(nèi),并且所有這些引用都不能“逃逸”到這個(gè)方法體以外的地方,那么HotSpot會(huì)要求JIT執(zhí)行一項(xiàng)優(yōu)化動(dòng)作 – 將局部變量上擁有的鎖省略掉。
這就是鎖省略(lock elision)。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注