名詞解釋:
JIT(Just-In-Time Compilation):實時編譯。
有關JIT的概念,可以看我的另一篇文章:《JIT實時編譯特性》
在JVM的實現中,為了提高JVM的性能和節省內存空間,JVM提供了一種叫做 “逃逸分析” 的特性,而且對於“逃逸分析” 這種特性,也是近年來大廠面試常問的知識點。今天,我們就一起來聊聊什么是逃逸分析。
逃逸分析的官方定義:一種確定指針動態范圍的靜態分析,它可以分析在程序的哪些地方可以訪問到指針。
很難理解對不對,簡單點說就是:一種分析手段,用於確定對象的作用范圍。
分析的結果:不逃逸、方法逃逸、線程逃逸。
- 不逃逸、方法逃逸:對象放到棧中(為了節約棧空間,還會做標量替換等操作,可參考《JIT實時編譯特性》)。放到棧中的對象會隨着方法結束而銷毀,把不必放到堆中的對象放到了棧中。減輕了垃圾回收的壓力。
- 線程逃逸:對象放到堆中。
下面舉例說明:
//不逃逸 public static void main(String[] args) { String sb = createStringBuffer("a", "b"); sb.length(); } public static String createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb.toString(); } //方法逃逸 public static void main(String[] args) { StringBuffer sb = createStringBuffer("a", "b"); sb.reverse(); } public static StringBuffer createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb; } //線程逃逸 public static void main(String[] args) { StringBuffer sb = createStringBuffer("a", "b"); new Thread(() -> { sb.reverse(); }).start(); } public static StringBuffer createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb; }
在Java代碼運行時,通過JVM參數可指定是否開啟逃逸分析,
-XX:+DoEscapeAnalysis : 表示開啟逃逸分析
-XX:-DoEscapeAnalysis : 表示關閉逃逸分析 從jdk 1.7開始已經默認開始逃逸分析,如需關閉,需要指定-XX:-DoEscapeAnalysis
那么有關Java逃逸分析的介紹就到這里了,有問題歡迎在評論區留言討論,我看到后也會回復的。
Tips:如果想看逃逸分析日志,可以添加java參數:-XX:+PrintEscapeAnalysis來打印。但是這個參數只有在debug版本的jdk版本有用。