編譯虛擬機jvm——openjdk的編譯

来源:http://www.cnblogs.com/abaoge/archive/2017/11/30/7932612.html
-Advertisement-
Play Games

java只所以被推廣,實際上很大原因是因為本身是跨平臺的,很大作用是因為虛擬機的關係。 一般情況下開發人員不需要關註虛擬機內部實現就可以日常開發了,但是有時候涉及到性能的時候就需要瞭解虛擬機的實現機制了。 那麼今天寫的內容更多的是關於編譯一套自己的虛擬機,為日後瞭解虛擬機底層原理鋪鋪路。 編譯虛擬機 ...


java只所以被推廣,實際上很大原因是因為本身是跨平臺的,很大作用是因為虛擬機的關係。

一般情況下開發人員不需要關註虛擬機內部實現就可以日常開發了,但是有時候涉及到性能的時候就需要瞭解虛擬機的實現機制了。

那麼今天寫的內容更多的是關於編譯一套自己的虛擬機,為日後瞭解虛擬機底層原理鋪鋪路。

編譯虛擬機可能會遇到很多坑,也很花費時間。也因大家的環境的差異,可能遇到的問題都不一致。

我只能說把自己遇到的問題都列出來,權當拋磚引玉了。

1首先我們應該下載openjdk的源碼,這個openjdk實際上是有一個版本歷史的,大家可以去瞭解一下,

  然後這裡面的源碼內容和oracle jdk內容大部分都是一致的,少數內容不一樣。  

  我這裡下載的openjdk 源碼是openjdk-7u75-src-b13-18_dec_2014.zip,每個人的版本可能不太一樣,不過   是openjdk的源碼就行。

2除了上面的東西要準備,其實還要準備一個oracle的jdk,這個jdk我用的是jdk-6u32-linux-x64.bin。

3然後是在linux上先準備好各種依賴,這些依賴獲得方式待會兒會講,另外要講的是,我這裡的linux系統

  是ubuntu的 16.04LTS 64位的,所以之前的東西也最好都準備64位的。

 

東西都準備好了,現在我們開乾!!!!

1如果之前你設置了java_home或者classpath環境變數,請先註釋掉。

2將openjdk-7u75-src-b13-18_dec_2014.zip解壓後得到openjdk文件夾,我們把他放到/usr下。

3執行jdk-6u32-linux-x64.bin,得到jdk1.6.0_32文件夾,我們講這個文件夾放到/usr/java下。

4輸入vim /etc/profile,在最後加入如下內容:

export LANG=C

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

export ALT_BOOTDIR=/usr/java/jdk1.6.0_32

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

export ALT_JDK_IMPORT_PATH=/usr/java/jdk1.6.0_32

#規定幾個線程來執行這個腳本
export HOTSPOT_BUILD_JOBS=4
export ALT_PARALLEL_COMPILE_JOBS=4

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

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/openjdk/build

export ALLOW_DOWNLOADS=true

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

unset JAVA_HOME

unset CLASSPATH

make 2>&1 | tee $ALT_OUTPUTDIR/build.log 

註意的是需要source /etc/profile,以更新配置。但是輸入後會馬上跑起來,但是現在是不會成功的,因為依賴那些還沒弄好。直接馬上接著按ctrl+c以暫停。

5在終端執行一些命令以安裝必要的依賴,命令如下:

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

有些地方還安裝了openjdk-6-jdk,其實這裡不安裝這個更好,我們用的是oracle的jdk來編譯我們的openjdk源碼,不建議用openjdk-6-jdk來編譯openjdk源碼,那也正是我build.sh腳本裡面指向的jdk地址是export ALT_BOOTDIR=/usr/java/jdk1.6.0_32的原因。

6現在我們到/usr/openjdk目錄去執行make sanity命令,檢查是否配置都沒問題了。如果沒有問題就會顯示

 

7萬事具備,只欠東風,輸入make,開始編譯,編譯出的東西會生成在/usr/openjdk/build目錄。

流程就是這樣的,不過期間會出現一些問題,根據他報的錯我們要修正一些錯誤,修正之後再繼續make命令接著編譯。

 

下麵是我遇到的一些錯誤和解決辦法。

 

1>

echo "*** This OS is not supported:" `uname -a`; exit 1;

openjdk/hotspot/make/linux/Makefile:240: recipe for target 'check_os_version' failed

解決:

將/openjdk/hotspot/make/linux/Makefile中的check_os_version下麵三行註釋掉

check_os_version:
#ifeq ($(DISABLE_HOTSPOT_OS_VERSION_CHECK)$(EMPTY_IF_NOT_SUPPORTED),)
# $(QUIETLY) >&2 echo "*** This OS is not supported:" `uname -a`; exit 1;
#endif

 

2>

undefined reference to `void G1SATBCardTableModRefBS::write_ref_array_pre_work<oopDesc*>(oopDesc**, int)'

解決:將hotspot/src/share/vm/gc_implementation/g1里的g1SATBCardTableModRefBS.cpp

template <class T> void G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) { if (!JavaThread::satb_mark_queue_set().is_active()) return; T* elem_ptr = dst; for (int i = 0; i < count; i++, elem_ptr++) { T heap_oop = oopDesc::load_heap_oop(elem_ptr); if (!oopDesc::is_null(heap_oop)) { enqueue(oopDesc::decode_heap_oop_not_null(heap_oop)); } } }內容下加上如下

//2017-10-19 Vicent_Chen added void G1SATBCardTableModRefBS::write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) { if (!dest_uninitialized) { write_ref_array_pre_work(dst, count); } } void G1SATBCardTableModRefBS::write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) { if (!dest_uninitialized) { write_ref_array_pre_work(dst, count); } } //2017-10-19 Vicent_Chen added

         將hotspot/src/share/vm/gc_implementation/g1里的g1SATBCardTableModRefBS.hpp如下部分

virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized) { if (!dest_uninitialized) { write_ref_array_pre_work(dst, count); } } virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized) { if (!dest_uninitialized) { write_ref_array_pre_work(dst, count); } }

註釋掉,然後在加入virtual void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized); virtual void write_ref_array_pre(narrowOop* dst, int count, bool dest_unintialized);

 

3>

Error: time is more than 10 years from present: 1136059200000

解決:

openjdk/jdk/src/share/classes/java/util/CurrencyData.properties文件中以下時間改成10年以內

AZ=AZM;2005-12-31-20-00-00;AZN

MZ=MZM;2006-06-30-22-00-00;MZN
RO=ROL;2005-06-30-21-00-00;RON

TR=TRL;2004-12-31-22-00-00;TRY

VE=VEB;2008-01-01-04-00-00;VEF

4>之後可能在編譯RMIServerImpl_Stub.class的時候,很可能是記憶體不夠了,因為我通過系統監視器觀察得到這段時間內記憶體在暴增,具體原因也不知道,但是我連續幾次在make命令重新來的時候,到最後一次

又成功了。所以遇到這種情況這種情況可以多次重來。最後一次記憶體就沒有暴增了。

 

編譯成功就是如下的樣子了:

 

 

之後在build文件夾內就能找到你編譯好的jdk。

謝謝大家,有什麼不明瞭的可以向我提問。

 


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

-Advertisement-
Play Games
更多相關文章
  • 判斷各個瀏覽器,然後進行解碼和加碼 ...
  • 輸入3個字元串,要求按由小到大的字母順序輸出 如 輸入franch england china,輸出結果是china england franch 三個數排序輸出,比較三個數的大小怎麼做? a=18 b= 9 c=30 a>b 交換 a=9 b=18 可不可以用選擇法?可不可以用冒泡法?但是這裡用不 ...
  • 第一階段:三年 我認為三年對於程式員來說是第一個門檻,這個階段將會淘汰掉一批不適合寫代碼的人。這一階段,我們走出校園,邁入社會,成為一名程式員,正式從書本 上的內容邁向真正的企業級開發。我們知道如何團隊協作、如何使用項目管理工具、項目版本如何控制、我們寫的代碼如何測試如何線上上運行等等,積累了一定的 ...
  • 1> 打開main.go文件,查看代碼 點擊快捷鍵F12,進入beego.go文件,查看代碼 2> 打開router.go文件,查看路由 3> 打開default.go文件,查看業務邏輯 4> 打開index.tpl文件,查看前臺頁面 5> 執行邏輯總結 第一步,進入main.go,編譯程式;第二步 ...
  • 本文介紹一下matplotlib的最基本用法。 這次我們要顯示一個線性方程的直線。 首先要引入matplotlib庫,一般是用plt這個簡寫的,我們就按照大多數人的慣例來進行命名: 下麵我們用numpy生成x軸上的數據:從 1到1,總共有50個點: 再定義一個線性方程: 接著把x和y在坐標軸上顯示出 ...
  • 英語里final這個單詞大家都知道是“最終的”意思,其實還有一個意思是“不可更改的”。在Java里,final關鍵字作“不可更改的”來解釋更合適,即由final修飾的東西是“不可更改的”。final可以修飾變數、成員方法和類,還可以修飾方法的參數,但參數歸根結底還是變數。下麵是詳細解釋。 作者: 蟬 ...
  • 一、回顧jQuery實現的ajax 首先說一下ajax的優缺點 jquery 實現的ajax 1 <!DOCTYPE html> 2 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>Title</title> 7 <scri ...
  • PyQt5 的 signal 與 slot 有所改變,例如,先定義一個 ZeroSignal 類: 使用時,一是綁定 slot 如下: 然後是找個機會發動之: 大約如此,完整代碼如下: OK! ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...