源碼編譯OpenJDK8

  1、前言
  
  2、源碼編譯OpenJDK8
  
  一、下載Ubuntu
  
  二、下載OpenJdk源碼
  
  三、下載Boot JDK
  
  四、安裝依賴
  
  五、配置腳本
  
  六、編譯成功的效果
  
  3、Netbeans調試JVM
  
  一、下載NetBeans 8.2
  
  二、下載oracle jdk 1.8
  
  三、安裝net beans
  
  四、配置Open JDK工程
  
  五、運行HelloWorld
  
  六、調試Hello World
  
  七、在netbeans中新建java工程,並調試jvm
  
  回到頂部
  
  1、前言
  
  前一陣子比較好奇,想看到底層(虛擬機、彙編)怎麼實現的java 併發那塊。
  
  volatile是在彙編里加了lock前綴,由於volatile能夠經過查看JIT編譯器的彙編代碼來看。
  
  可是原子類,原本在jvm中就是彙編實現的,反而無法看。若是能實際跟蹤一下斷點,應該也算實際驗證了。
  
  這邊基本參照下面文章來的,補充了不少讓初學者頭疼的細節,並拓展了一部分,
  
  包括調試java 原子類在jvm中的實現的一些細節。
  
  https://marcin-chwedczuk.github.io/debugging-openjdk8-with-netbeans-on-ubuntu
  
  源碼編譯OpenJDK8,主要有如下幾個步驟:
  
  下載Ubuntu
  
  下載OpenJdk源碼
  
  下載Boot  JDK,通常要比當前要編譯的版本低
  
  安裝必要的依賴
  
  configure && make
  
  上面幾步搞完,基本虛擬機就可用了。但離調試,還有一點點距離。
  
  用NetBeans調試JVM代碼,有如下幾個步驟:
  
  下載NetBeans
  
  配置OpenJdk工程
  
  配置Java工程
  
  Debug OpenJdk(即虛擬機源碼)
  
  回到頂部
  
  2、源碼編譯OpenJDK8
  
  一、下載Ubuntu
  
  我用的16.04,連接地址:https://www.cmylept.cn /download/alternative-downloads
  
  我是用vmvare裝的,配置建議給高一點。
  
  二、下載OpenJdk源碼
  
  據原文說法,OpenJDK 使用Mercurial進行版本管理。另一個名叫AdoptOpenJDK project.提供了OpenJDK的鏡像,可讓咱們用git下載。
  
  站點的官網以下:https://www.cmylli.com adoptopenjdk.net/about.html
  
  主頁上說他們的目標就是:
  
  Provide a reliable source of OpenJDK binaries for all platforms, for the long term future.
  
  據個人使用體驗來講,以前編譯過一次OpenJDK,各類報錯,各類改源碼才能編譯經過。此次確實編譯很順,代碼一句沒改。
  
  看起來,代碼仍是比較可靠的。
  
  不扯別的了,直接clone搞下來吧,我這邊是直接在/home/ckl目錄下執行的shell:
  
  git clone --depth 1 -b master https://github.com/AdoptOpenJDK/openjdk-jdk8u.git
  
  三、下載Boot JDK
  
  編譯過jdk的同窗應該知道,咱們得先有隻母雞才能編譯openJDK源碼。
  
  這邊我用的oracle的jdk 1.7,這邊貼個csdn的下載連接,我那天弄的時候官網速度太慢。
  
  https://download.csdn.net/download/qq_33499492/10288883
  
  怎麼安裝就不說了,我解壓後放在/usr/local
  
  記得修改環境變量(/ect/profile):
  
  export JAVA_HOME=/usr/local/jdk1.7.0_80
  
  export JRE_HOME=${JAVA_HOME}/jre
  
  export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
  
  export PATH=${JAVA_HOME}/bin:$PATH
  
  而後,source /ect/profile 使之生效。
  
  四、安裝依賴
  
  複製代碼
  
  sudo apt install \
  
  libx11-dev \
  
  libxext-dev \
  
  libxrender-dev \
  
  libxtst-dev \
  
  libxt-dev \
  
  libcups2-dev \
  
  libfreetype6-dev \
  
  libasound2-dev
  
  複製代碼
  
  這個依賴不夠,我這邊裝的時候,還報了一些依賴缺失,直接安裝報錯提示裏的執行命令下載就完了。
  
  我這裏遇到比較坑的一點是(固然我對ubuntu徹底不熟),一開始用的是官方的repository 源,後來換成阿里雲的,各類報錯。
  
  嚇得我趕忙改回來了,就沒問題了。
  
  這裏遇到問題能夠諮詢我。
  
  五、配置腳本
  
  在/home/ckl/openjdk-jdk8u下,新建腳本build.sh:
  
  build.sh:
  
  bash ./configure --with-target-bits=64 --with-boot-jdk=/usr/local/jdk1.7.0_80/ --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
  
  make all ZIP_DEBUGINFO_FILES=0
  
  給build.sh增長可執行權限並執行:
  
  chmod +x build.sh
  
  ./build.sh
  
  六、編譯成功的效果
  
  切換到對應目錄下:
  
  /home/ckl/openjdk-jdk8u/build/linux-x86_64-normal-server-slowdebug/jdk/bin
  
  ./java -version
  
  在該目錄下,新建個HelloWorld來運行一下:
  
  public class HelloWorld {
  
  public static void main(String[www.ztyLegw.cn] args) {
  
  System.out.println("hello world");
  
  }
  
  }
  
  回到頂部
  
  3、Netbeans調試JVM
  
  一、下載NetBeans 8.2
  
  下載安裝主要參考:
  
  https://netbeans.org/community/releases/82/install.html
  
  NetBeans主頁上,最新版本出到11.0了,可是在網上看到都是用的NetBeans 8開頭版本的,有時間再折騰吧。
  
  我這裏下載的是8.2,連接:
  
  https://netbeans.org/downloads/8.2/
  
  由於OpenJDK是c++寫的,因此咱們必須選擇帶C/C++支持的,我這裏直接選All。
  
  另外,注意選linux平臺,最好選英語,省得出幺蛾子。
  
  二、下載oracle jdk 1.8
  
  爲啥又要下載jdk? 這個jdk不是編譯openJdk源碼用的那個,這個是運行NetBeans 8.2須要。
  
  The Java SE Development Kit (JDK) 8 is required to install NetBeans IDE.
  
  下完安裝後,把環境變量裏設的jdk路徑改掉吧:
  
  export JAVA_HOME=/usr/local/jdk1.8.0_211
  
  export JRE_HOME=${JAVA_HOME}/jre
  
  export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
  
  export PATH=${JAVA_HOME}/bin:$PATH
  
  source /etc/profile
  
  三、安裝net beans
  
  安裝:
  
  ./netbeans
  
  安裝過程,記得不要所有默認,能夠本身定製化:
  
  四、配置Open JDK工程
  
  安裝完成後,在桌面上,會生成一個圖標,直接雙擊啓動。
  
  後面的步驟,能夠參考:
  
  https://marcin-chwedczuk.github.io/debugging-openjdk8-with-netbeans-on-ubuntu
  
  而後接下來幾步均可以直接next,最後點finish會開始configure。
  
  五、運行HelloWorld
  
  配置咱們的openjdk工程去運行以前寫的HelloWorld程序。
  
  對着openjdk-jdk8u工程,右鍵選擇properties:
  
  選擇編譯出的jdk來運行咱們的class:
  
  應該能看到輸出Hello World了。
  
  六、調試Hello World
  
  System.out.println(...)會調用jdk/src/share/native/java/io/io_util.c的writeBytes
  
  直接在該函數打個斷點,而後debug
  
  不出意外,應該會停到該斷點。
  
  七、在netbeans中新建java工程,並調試jvm
  
  咱們來調一個有用點的程序,看看原子類在jvm中的實現究竟是不是像網上的博客那樣運行的。
  
  先像上面這樣,建個java工程,寫點代碼,而後運行。
  
  複製代碼
  
  import java.util.concurrent.atomic.AtomicBoolean;
  
  import java.util.concurrent.atomic.AtomicInteger;
  
  /**
  
  *
  
  * @author ckl
  
  */
  
  public class TestSample {
  
  private static AtomicInteger stop = new AtomicInteger(12);
  
  /**
  
  * @param args the command line arguments
  
  */
  
  public static void main(String[www.yuntianyul.com] args) {
  
  Boolean result = stop.compareAndSet(1314, 1413);
  
  // TODO code application logic here
  
  if (result){
  
  System.out.println(" true result ");
  
  }else {
  
  System.out.println("false result");
  
  }
  
  }
  
  }
  
  複製代碼
  
  調試jvm:
  
  對着openjdk-jdk8u工程點右鍵,properties。
  
  創建斷點,cas調用通常會調用unsafe.cpp的如下代碼:
  
  斷點ok了,而後點選中openjdk-jdk8u工程後,點擊debug按鈕:
  
  果真,程序立刻就停在這了。可是,cas操做可能在不少地方都調用了,因此咱們要仔細觀察Variables窗口,看看是否是咱們發起的那個調用:
  
  跳過了十屢次之後。。。
  
  。。。
  
  稍微跟一下:
  
  直接進到這段彙編了,用了cmpxchg指令來實現cas,還加了lock前綴(mp爲1)。lock前綴下次講。主要是鎖總線,或者鎖緩存,達到原子操做的目的。html

相關文章
相關標籤/搜索