虽然写了很多年的Java代码,但是基本上只把JVM当blackbox处理。介绍JVM的书也看过几本,但效果不佳。看OpenJDK代码?提不起兴趣。最近有几个礼拜的空闲时间,于是我决定用GO语言写一个JVM,彻底征服JVM这头怪兽!
为什么选择GO
首先不想用动态语言来写。实现JVM的初衷就是想离机器更近一点,所以排除了JavaScript、Python、Ruby等语言。其次也不想用Java来写,原因基本同上。还有一个原因是自己对Java太熟悉了,用它来写,没挑战性。再次也不想用C/C++,原因是自己不喜欢这两个语言。C过于底层,C++过于复杂。所以最终选择了GO。
GO是Google发布的语言,编译型,接近底层,一定程度上可以充当系统语言来使用。GO的语法很简洁,学习曲线平滑,文档也比较详细。而且GO跨平台,有垃圾回收机制,安全性也好,总之GO语言介于C和Java之间,是个不错的选择。当然,GO也有很多缺点,最大的问题就是GO的官网在国内无法访问,导致各种不便。好在国内有很多GO语言相关的网站,从这些站点可以下载GO的安装程序或者访问godoc。另外GO语言本身也有一些缺陷,比如奇怪的错误处理方式,不支持范型,等等。
基本思路
我们都知道,要想运行Java程序,实际上需要JRE。而完整的JRE包括两部分:JVM和类库(class libraries)。相比JVM来说,要想实现一套完整的类库,需要更加庞大的工作量。好在对于Oracle发布的JDK来说,类库的大部分代码已经是开源的了,任何人都可以看到。这部分Java代码编译好之后,就是rt.jar。因此基本思路就是:用GO实现JVM,然后这个JVM必须能够使用rt.jar来当作类库。具体工作实际上可以分成两部分,第一部分是用GO实现JVM本身,第二部分是用GO实现rt.jar里相应class的native方法。细节就不过多描述了。
目前的进展
经过三个礼拜的努力,现在这个JVM已经基本成型了。大约用了一周多的时间,HelloWorld程序就可以跑了,但是用了一些hack。第二周继续完善JVM,实现必要的native方法。第三周的大部分工作,都是实现rt.jar里的native方法。但就目前来说,这个JVM还很不完整,还有很多地方需要完善,比如线程、文件、反射,等等。下一步计划就是完善这些地方,实现更多的native方法,改bug,做一些优化,目标是实现一个完整的JVM。
项目地址
如果对这个项目感兴趣,可以访问它的Github主页:https://github.com/zxh0/jvm.go。如果大家想鼓励我的话,就给它一个Star吧:)
编译和运行
这个项目主要是在Mac OS X 10.7.5上面开发的,GO语言版本是go1.4,rt.jar是从Java 1.8.0_11-b12里拷贝的。暂时还没有在Windows下做测试。
编译:
- 安装go1.4
- 克隆jvm.go
- export GOPATH=path/to/jvm.go/
- go install jvmgo
install命令正常执行之后,在path/to/jvm.go/bin/目录下就会出现可执行文件jvmgo
运行jvmgo:
- cd到path/to/jvm.go/bin/目录
- jvmgo -cp path/to/rt.jar:path/to/classes HelloWorld