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..0_32

#同上,我之前使用的是openjdk编译的,后面运行hotspot时出现问题替换为oracleJDK,读者可以直接替换为OracleJDK

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

#规定几个线程来执行这个脚本
export HOTSPOT_BUILD_JOBS=
export ALT_PARALLEL_COMPILE_JOBS= #要编译的内容,读者可以根据需要自行选择 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 >& | 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。

谢谢大家,有什么不明了的可以向我提问。

编译虚拟机jvm——openjdk的编译的更多相关文章

  1. 深入解析java虚拟机-jvm运行机制

    转自oschina 一:JVM基础概念 JVM(Java虚拟机)一种用于计算设备的规范,可用不同的方式(软件或硬件)加以实现.编译虚拟机的指令集与编译微处理器的指令集非常类似.Java虚拟机包括一套字 ...

  2. 走进JVM之一 自己编译openjdk源码

    想要深入了解JVM,就必须了解其实现机制.了解JVM实现的最好方法便是自己动手编译JDK.好了,让我们开始吧! 1.  准备工作 获取OpenJDK源码 本次编译选择的是OpenJDK7u,官方源码包 ...

  3. JAVA 文件编译执行与虚拟机(JVM)简单介绍

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...

  4. openjdk 完全编译指南

    从openjdk.java.net下载openjdk的软件包,你就获得了所有相关的源码. 强烈建议首先仔细看懂 README-builds.html 指南. 在执行 make all 之前,首先要 执 ...

  5. JVM源码分析-JVM源码编译与调试

    要分析JVM的源码,结合资料直接阅读是一种方式,但是遇到一些想不通的场景,必须要结合调试,查看执行路径以及参数具体的值,才能搞得明白.所以我们先来把JVM的源码进行编译,并能够使用GDB进行调试. 编 ...

  6. JVM(十三):后端编译优化

    JVM(十三):后端编译优化 在 JVM(一):源文件的转变 中我们介绍了 Java 中的前端优化,即将 Java 源代码转换为字节码文件.在本文中,我们将介绍字节码文件如何转换为本地机器码,并如何对 ...

  7. 《深入理解JAVA虚拟机》-自己动手编译JDK

    环境 Ubuntu12.4-http://mirrors.163.com/ubuntu-releases/12.04/ --需要安装纯英文版,避免中文引起不必要的麻烦 OpenJDK7-https:/ ...

  8. JVM JIT动态编译

    一.概述 1.1 基本概念 a. 动态编译(dynamic compilation)指的是"在运行时进行编译":与之相对的是事前编译(ahead-of-time compilati ...

  9. 【Java】实战Java虚拟机之五“开启JIT编译”

    今天开始实战Java虚拟机之五“开启JIT编译” 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实战Ja ...

随机推荐

  1. win10 uwp 右击选择 GridViewItem

    有时候我们需要选择一个 GridView 的一项,通过我们右击. 于是我们需要在 GridView 的 SelectionMode 为 Single ,IsRightTapEnabled 为True ...

  2. [NOIP2014][DP]飞扬的小鸟

    [NOIP2014]飞扬的小鸟 ——!x^n+y^n=z^n 题目描述: Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画 ...

  3. HTML5-前端开发很火且工资很高?

    前言 晚上逛论坛看到一篇对从事HTML5前端开发的文章写的非常不错,和目前的市场形势差不多,然后我在其基础上给大家进行加工总结一下分享给大家.今天我们谈论的话题是<<为什么从事HTML5前 ...

  4. 本地连接 vmware服务器

    在本机中装载虚拟机,安装redhat.需要调试使用redhat可以与Windows进行通讯. 分为多步,在此前提下,默认你已经安装好且可以vm 和虚拟机 1:点击虚拟机>设置>添加网络适配 ...

  5. 树莓派.使用Node.js来制作一个作业检查仪

    先上图 前段时间, 花了点时间给女儿做了个数学习题的小程序 首页 做题界面(题目每次都随机生成, 加减乘除都有) 做题记录 现在问题来了, 怎么才能随时知道作业有没有完成呢? 每次打开做题记录页面刷新 ...

  6. mybatis返回int类型报null

    解决这个问题,是当查出来为NULL时,结一个默认值,如:0. MySQL: SELECT IFNULL(MAX(id),0)AS sort FROM table Oracle: SELECT nvl( ...

  7. sessionStorage,UserDataStorage,cookie全兼容写法存在的问题

    最近央视播出了中国诗词大赛,看到了一首诗,送给大家 <春宵·春宵一刻值千金> 作者:苏轼 [宋代] 春宵一刻值千金,花有清香月有阴. 歌管楼台声细细,秋千院落夜沉沉. 好了,言归正传,今天 ...

  8. JavaScript 中的对象引用

    ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型,拥有方法的类型和不能拥有方法的类型,还可以分为可变类型和不可变类型,其实这些叫法都是依据这两 ...

  9. Linux 新建文件/文件夹,删除文件文件夹,查找文件 打开文件

    1.新建文件夹:mkdir xx 2.新建文件: touch 1.py 3.删除文件/文件夹: rm -r xx  rm 1.py 4.打开文件:cat 1.py 只显示前几行 :head -2 1. ...

  10. 深入分析Android动画(一)

    动画的分类: ①View动画 View动画顾名思义其作用对象为View,包含平移.缩放.旋转.透明,这四类变化分别对应着Animation的子类TranlateAnimation.ScaleAnima ...