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