理解Java中的逃逸分析


名詞解釋:

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版本有用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM