一 开天辟地 -- Hello JVM!
一 背景
工作的内容大部分和Android相关,最开始的工作是C/C++ 主要是OS 底层的内容,对于二进制的执行有一些了解。后来的工作主要是应用开发,对于解释型的语言如何工作只有一个模糊的概念,随着工作的深入,对这块的内容的苛求也越来越强烈。虽然 “read the fucking code ” 是最好的办法,但是这块代码量太大,往往无从下手。一次机会看到了《自己动手写java 虚拟机》这本书,简明扼要,既有概念讲解,也有代码实践,把Java 虚拟机的运行原理讲的通俗易懂,在一头雾水中找到了一个路径。读完之后念念不忘,刚好这段实践有一点时间,准备按照这本书的章节安排自己实现一个java 虚拟机。
书的作者使用的是Go 语言开的的JVM, 可能作者从事的是服务端开发。Go 语言简单的了解过,但是工作中没有实践,不敢班门弄斧。而且从事的工作主要是Android 相关的开发,Android 主要是C C++ Java 语言,因此想写一个Android 开发相关
看起来更容易理解的JVM。最开始考虑的是C C++, 实践了一下后放弃了。一个是语言的易用性,IDE,好久不写底层的代码,写起来以后 发现效率太低,也没有太多的时间来做这个东西,而java 易用性,还有丰富的开源类库支持,不用花大量的时间在细节上,可以很快的实现我们的想法。觉得使用java 来写这个Jvm 更靠谱。如果是C C++ 估计自己都坚持不下去了。 这样带来一个问题:是先有鸡,还是先有蛋。其实用Java 实现java 虚拟机 SUN 公司已经有一个实践。如果能够对JVM 有一个了解后,这个就不是问题了。java 实现JVM的另外一个问题是JNI 无法实现,但是了解了JVM的原理后,结合其他一些资料,应该也能了解JNI的原理。所以JNI的内容不再这个范围之内。我们的主要内容是JVM 解释JAR 文件如何运行。
二 准备工作
Mac OS X 10.12.6
IDE:IntelliJ IDEA 2017.3.1 (Community Edition)
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)
1. 工程目录
主要是两个 Mani 和 Jvm 类
2. Main 类
Main 类很简单,就是一个jar 包的入口, 在 main 函数中定义一些参数,启动JVM。
public class Main {
static final String[] mJvmArgs = {"java", "-version", "-help"};
public static void main(String[] args) {
System.out.println("Hello JVM !!!");
Jvm.parseCmd(mJvmArgs);
Jvm.startJvm(mJvmArgs);
}
}
3. Jvm 类
Jvm 类是Java 虚拟机的入口,在命令行运行 java 程序的时候需要传入一些参数。支持一些参数的解析:
- h help 帮助方法
- v 显示版本信息
- X XJre JAVA_HOME 路径
- cp classpath class 文件路径
参数的解析使用了Apache 的 commons-cli 包,
public static void parseCmd(String [] args){
Options options = new Options();
options.addOption("h", "help", false, "Show Usage");
options.addOption("v", "version", false, "Show Version");
options.addOption("cp", "classpath", true, "Jar path");
options.addOption("X", "Xjre", true, "Jar path");
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("h")) {
printUsage();
}
if (cmd.hasOption("version")) {
System.err.println(TAG+"Version : " +mVersion);
}
if (cmd.hasOption("classpath")) {
mClassPath = cmd.getOptionValues("classpath");
}
if (cmd.hasOption("X")) {
mXJre = cmd.getOptionValue("Xjre");
}
if(cmd.getArgList().size() == 0){
printUsage();
}
} catch (ParseException e) {
System.err.println(TAG+e.getMessage());
e.printStackTrace();
}
}
启动虚拟:
public static void startJvm(String [] args){
System.err.println(TAG+"startJvm !!!");
}
[图片上传失败...(image-2646ea-1517113349332)]