1. 程式人生 > >極速體驗編譯openjdk8(docker環境)

極速體驗編譯openjdk8(docker環境)

本文不講解編譯openjdk8的過程,而是專注於用最少的步驟把openjdk8原始碼編譯構建成jdk。

進行本文的實踐有個前提:請讀者們先在電腦上安裝docker

總的來說整個過程只有六步,如下:
1. 指定映象建立一個容器,這個映象中已經把編譯所需的工具和原始碼都準備好了;
2. 進入容器;
3. 找到openjdk8原始碼位置,有興趣的讀者此時可以修改原始碼;
4. 在指定目錄開始configure;
5. configure完成後開始編譯;
6. 編譯成功,進入build目錄,檢查驗證全新的jdk;

接下來開始實戰吧:

指定映象建立容器

在控制檯執行命令:

docker run
--name=compilejdk -idt bolingcavalry/bolingcavalryopenjdk:0.0.1

這個命令會先去hub.docker.com網站下載映象bolingcavalry/bolingcavalryopenjdk:0.0.1,然後建立一個名字叫compilejdk的容器;

進入容器

執行以下命令即可進入容器:

docker exec -it compilejdk /bin/bash

找到openjdk8原始碼位置,修改jdk原始碼

和本次編譯相關的資源都放在/usr/local/openjdk下面了,如下圖:

這裡寫圖片描述

  1. 我們這次要修改的檔案是/usr/local/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp;
  2. 執行命令vi /usr/local/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp編輯這個檔案;
  3. 找到方法ObjectMonitor::exit(bool not_suspended, TRAPS)
  4. 再找到該方法裡面的int QMode = Knob_QMode ;這行程式碼;
  5. 在下面新增一行程式碼printf(“**-QMode : %d”, QMode);,也就是將QMode的值在控制檯打印出來,如下圖:

這裡寫圖片描述

修改完畢後儲存退出vi;

新增這行程式碼的作用,是在每個synchronize{}程式碼塊結束的時候,也就是執行緒釋放鎖的時候,在控制檯將QMode這個引數的值打印出來;

在指定目錄開始configure

回到目錄/usr/local/openjdk,執行以下命令進行configure:

./configure --with-debug-level=slowdebug

執行完畢的效果如下圖所示:

這裡寫圖片描述

開始編譯

回到目錄/usr/local/openjdk,執行以下命令開始編譯:

make all ZIP_DEBUGINFO_FILES=0 DISABLE_HOTSPOT_OS_VERSION_CHECK=OK CONF=linux-x86_64-normal-server-slowdebug

編譯耗時長短和機器硬體配置有關,我的2014版mac pro13大約用20分鐘完成編譯,執行完畢的效果如下圖所示:

這裡寫圖片描述

檢查和驗證全新的jdk

進入目錄/usr/local/openjdk/build/linux-x86_64-normal-server-slowdebug,內容如下:

這裡寫圖片描述

圖中的jdk資料夾中就是全新的jdk,進入這個資料夾再進入裡面的bin目錄,執行./java -version命令可以看到如下內容:

這裡寫圖片描述

如上圖“1.8.0-internal-debug-_2017_08_30_13_00-b00“表示是最新構建的jdk版本,至於前面那幾行“**-QMode : 0“就是系統執行了釋放鎖的api,導致我們新增的那行程式碼被執行了;

接下來我們寫個java類在這個jdk上執行試試,在/usr/local/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin目錄下,用vi命令建立Test.java檔案,內容如下:

public class Test{
    public static void main(String[] args){
        Object lock = new Object();

        new Thread(()->{
            synchronized(lock){
                System.out.println("1. get lock success");
                System.out.println("1. release lock start");
            }

            System.out.println("1. release lock end");
        }).start();

        new Thread(()->{
            synchronized(lock){
                System.out.println("2. get lock success");
                System.out.println("2. release lock start");
            }

            System.out.println("2. release lock end");
        }).start();
    }
}

程式碼很簡單,就是執行了一次持有鎖再釋放鎖的操作;

還是在jdk/bin目錄下,執行以下命令編譯java檔案,注意,一定要加上./,否則就不會使用最新的jdk:

./javac Test.java

執行完javac命令之後,再執行./java Test就能把編譯好的Test.class檔案執行起來了,效果如下:
這裡寫圖片描述

如上圖所示,在釋放鎖的時候會把我們新增的程式碼打印出來;

以上就是在docker下最快速完成openjdk8編譯的過程了,是不是很容易呢?如果您想了解更多細節,例如編譯環境需要準備哪些材料,映象如何製作,甚至如何用GDB給jvm打斷點單步除錯,請參考下面這兩篇文章: