java逃逸是什么東西? 我怎么知道是否開啟了逃逸分析? 為什么對象可以不在堆上分配內(nèi)存? 代碼示例
1.java逃逸是什么東西? 可以理解為jvm為了減少GC和優(yōu)化內(nèi)存使用做出的一種優(yōu)化方案,由JIT動態(tài)編譯器進(jìn)行優(yōu)化,所以通過反編譯是看不出來的 2.我怎么知道是否開啟了逃逸分析? 逃逸分析的JVM參數(shù)是 DoEscapeAnalysis,通過java -client -XX: PrintFlagsInitial 打印一下JVM參數(shù)默認(rèn)值(我這里是1.8版本)  可以發(fā)現(xiàn)默認(rèn)是開啟了逃逸分析。
3.為什么對象可以不在堆上分配內(nèi)存? JVM逃逸做了如下幾種對代碼的優(yōu)化,鎖消除,標(biāo)量替換等手段,將對象所需空間在棧中分配,減少gc回收,鎖消除的JVM參數(shù)是EliminateLocks ,標(biāo)量替換是EliminateAllocations,還是通過上面方法去搜索,發(fā)現(xiàn)默認(rèn)是開啟的(1.8版本) 
 4.代碼示例 首先是鎖消除,對象在方法內(nèi)創(chuàng)建,并且在方法內(nèi)加鎖,這樣是沒有意義的,每一次調(diào)用方法都會new新的對象,并對新的對象加鎖
private void sync() {
Object o = new Object();
synchronized(o) {
System.out.println(o);
}
}
jit動態(tài)編譯代碼優(yōu)化為 private void sync(){
Object o = new Object();
System.out.println(o);
}
在方法內(nèi)部創(chuàng)建一個沒有被外部引用的對象,就會不會發(fā)生逃逸,但是如果像下圖這種,方法內(nèi)部的對象被拿到外部使用了那么就發(fā)生了逃逸 private StringBuilder sync(String a,String b){
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
return sb;
}
如果對象僅僅在方法內(nèi)部使用,不將引用傳遞出去,是不會發(fā)生逃逸的,比如改成這樣 private String sync(String a,String b){
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
return sb.toString();
}
這樣StringBuilder 的引用就消失了,會順利的被回收掉,下面是標(biāo)量替換,對象在方法內(nèi)創(chuàng)建,無外部引用,會被標(biāo)量所替換,減少GC和堆上內(nèi)存使用 private void sync() {
Sync sync= new Sync(1,2);
System.out.println("x" sync.x "y" sync.y);
}
class Sync{
public Sync(int x, int y) {
this.x = x;
this.y = y;
}
private int x;
private int y;
}
替換結(jié)果 private void sync(){
int x = 1;
int y = 2;
System.out.println("x" sync.x "y" sync.y);
}
參考博客 JIT百度百科 來源:https://www./content-1-418951.html
|