極速體驗編譯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下面了,如下圖:
- 我們這次要修改的檔案是/usr/local/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp;
- 執行命令vi /usr/local/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp編輯這個檔案;
- 找到方法ObjectMonitor::exit(bool not_suspended, TRAPS);
- 再找到該方法裡面的int QMode = Knob_QMode ;這行程式碼;
- 在下面新增一行程式碼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打斷點單步除錯,請參考下面這兩篇文章: