走進JVM之一 自己編譯openjdk源碼

来源:http://www.cnblogs.com/ACFLOOD/archive/2016/05/25/5528035.html
-Advertisement-
Play Games

想要深入瞭解JVM,就必須瞭解其實現機制。瞭解JVM實現的最好方法便是自己動手編譯JDK。好了,讓我們開始吧! 1. 準備工作 獲取OpenJDK源碼 獲取OpenJDK源碼 本次編譯選擇的是OpenJDK7u,官方源碼包:https://jdk7.java.net/source.html 系統需求 ...


想要深入瞭解JVM,就必須瞭解其實現機制。瞭解JVM實現的最好方法便是自己動手編譯JDK。好了,讓我們開始吧!

1.  準備工作

  • 獲取OpenJDK源碼

本次編譯選擇的是OpenJDK7u,官方源碼包:https://jdk7.java.net/source.html

  • 系統需求

為了提高效率,儘量選擇Linux MacOS作為編譯平臺。本次使用Ubuntu12.04進行編譯。仔細閱讀源碼包中README-builds.html文檔,就可以構建編譯環境了。

   

2.  配置編譯環境

  • 編譯依賴

OpenJDK包括虛擬機Hotsport | JDK API | JAXWS | JAXP等。需要各種編譯依賴,包括C++C的編譯環境,編譯JavaJDK(稱為Bootstrap JDK),還有用於執行java代碼的Ant腳本等等。這些依賴在Linux中都可以通過命令一次安裝完成。

sudo apt-get install build-essential gawk m4 libasound2-dev libcups-dev libxrender-dev xorg-dev xutils-dev x11proto-print-dev binutils libmotif3 libmotif-dev ant

 

當然,也可以在命令裡面加上openjdk-6-jdk,但是由於openjdk在後面的編譯中出現了bug,所以還是建議大家安裝Oracle jdk。註意,bootstrap JDK版本必須在6以上。

  • 環境變數

OpenJDK在編譯時會讀取許多環境變數,所以必須對Linux的環境變數進行配置。使用VIM編輯/etc/profile vim /etc/profile

具體在profile中添加的環境變數如下

export LANG=C

#BootStrap-JDK的安裝路徑,替換為自己bootstrap-JDK的路徑

export ALT_BOOTDIR=/usr/lib/jvm/java-6-openjdk-i386

#同上,我之前使用的是openjdk編譯的,後面運行hotspot時出現問題替換為oracleJDK,讀者可以直接替換為OracleJDK

export ALT_JDK_IMPORT_PATH=/usr/lib/jvm/java-6-openjdk-i386

#要編譯的內容,讀者可以根據需要自行選擇

export BUILD_LANGTOOLS=true

#export BUILD_JAXWS=false

#export BUILD_JAXP=false

#export BUILD_CORBA=false

export BUILD_HOTSPOT=true

export BUILD_JDK=true

export SKIP_COMPARE_IMAGES=true

BUILD_DEPLOY=false

BUILD_INSTALL=false

#編譯結果存放的路徑,建議存放在openjdk源碼中build文件夾

export ALT_OUTPUTDIR=/usr/dev/jvm/openjdk/build

export ALLOW_DOWNLOADS=true

#這兩個環境變數需要去掉,不然會出問題

unset JAVA_HOME

unset CLASSPATH

 

添加完成後,進入openjdk源碼路徑,通過make sanity命令來檢查設置是否正確,如果正確,會返回Sanity check passed

   

3.  開始編譯OpenJDK

  • 使用make命令

openjdk目錄下,輸入make命令,正常情況下大概需要30分鐘左右,具體速度根據機器性能決定。編譯正常結束後,會出現日誌清單展示內容,如圖

  • 查看編譯結果

進入build/j2sdk-image目錄下,查看整個JDK的編譯結果,運行java –version

4.  運行HotSpot

  • 編輯env.sh

虛擬機的輸出結果存放在build/hotspot/outputdir/linux_i486_compiler2路徑下,如圖

使用VIM編輯product目錄下的env.sh

我們發現裡面已經有了JAVA_HOME CLASSPATH HOTSPOT_BUILD_USER等環境變數,我們還需要添加一個LD_LIBRARY_PATH,否則在運行時還會出現問題。

LD_LIBRARY_PATH=.:${JAVA_HOME}/jre/lib/i386/native_threads:${JAVA_HOME}/jre/lib/i386:

export LD_LIBRARY_PATH

 

  • 執行命令啟動JVM

使用如下命令,啟動虛擬機,輸出版本號

. ./env.sh

./gamma –vesion

 

成功結果如圖

至此成功編譯運行OpenJDK7,下麵講講過程中遇到的問題。

   

5.  編譯運行過程中可能會遇到的問題

  • OpenJDK6.0bug

使用OpenJDK6.0作為bootstrap JDK的話,在編譯及運行過程中可能會出現類似於這樣的錯誤,運行./gamma時也可能出現,這類錯誤都屬於OpenJDK-6中的bug

relocation error: /usr/lib/jvm/java-6-openjdk-i386/jre/lib/i386/libjava.so: symbol JVM_FindClassFromCaller, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference

 

網上提供的一種解決方案是通過find –name 'CurrencyData.properties' 找到CurrencyData文件,把文件中的時間全部修改為10年以內。然而我嘗試了這種方法並不能解決問題,於是嘗試把Bootstrap JDKopenjdk-6更換為OracleJDK6,終於解決問題。

  • 未取消掉JAVA_HOME變數

如果沒有在環境變數中添加unset JAVA_HOMEmake Sanity時會出現以下錯誤

ERROR: Your JAVA_HOME environment variable is set. This will most likely cause the build to fail. Please unset it and start your build again.

Exiting because of the above error(s).

make: *** [post-sanity] Error 1

 

/etc/profile中添加unset JAVA_HOME以解決問題

還有許多在編譯過程中遇到的問題,在前文中已經進行彌補和完善,相信大家按照這些步驟進行編譯,會省去不少麻煩。

   

6.  總結

通過自己動手編譯OpenJDK-7的源碼,我們可以深入瞭解JVM的編譯環境以及運行過程。通過解決編譯過程中遇到的問題,為後續對JVM的深入探索打下了良好的基礎。在此基礎上,我們還可以通過NetBeansHotspot進行運行和調試,進一步瞭解JVM源碼的結構與細節。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • PHP 支持八種原始類型(type)。 四種標量類型: 兩種複合類型: 兩種特殊類型: 字元串類型 一個字元串是一串字元的序列,就像 "Hello world!"。 定義字元串有 3 種方法: 1.單引號定義 將字元串用單引號(')括起來是定義字元串最簡單的方法: 如果字元串中有單引號,那麼需要使用 ...
  • Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space fo ...
  • Given an array and a value, remove all instances of that value in place and return the new length. Do not allocate extra space for another array, you ...
  • Day 15 集合框架01 TreeSet02 TreeSet存儲自定義對象03 二叉樹04 實現Comparator方式排序05 TreeSet練習06 泛型概述07 泛型使用08 泛型類09 泛型方法10 靜態方法泛型11 泛型介面12 泛型限定13 泛型限定2 01 TreeSet |--Se ...
  • 出自:http://www.diybl.com/course/3_program/python/20111130/563643.html 模塊名: 小寫字母,單詞之間用_分割 ad_stats.py 包名: 和模塊名一樣 類名: 單詞首字母大寫 AdStats ConfigUtil 全局變數名(類變 ...
  • 目標:tomcat伺服器提供的介面,不能在其他域中訪問的時候,需要增 Access-Control-Allow-Origin:* 直接配置的方法很多,但是我一個沒有成功過,所以只能自己寫攔截器了。 1. 編寫攔截器代碼 新建一個類,實現Filter介面,代碼如下 2. 配置web.xml 3. 刪除 ...
  • 01 關於本書 02 代碼約定 03 關於例子 04 如何聯繫我們 1 核心模塊 11 介紹 111 內建函數和異常 112 操作系統介面模塊 113 類型支持模塊 114 正則表達式 115 語言支持模塊 12 _ _builtin_ _ 模塊 121 使用元組或字典中的參數調用函數 1211 E ...
  • Write a function that takes a string as input and reverse only the vowels of a string. Example 1:Given s = "hello", return "holle". Example 2:Given s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...