Java Virtual Machine简称为JVM,用于执行编译好的.class文件。
JVM由类加载器、运行时数据区(JVM内存)、执行引擎和本地接口四部分组成,.class文件的执行由这四部分共同配合完成。

类加载器:负责将class文件加载到JVM内存。JVM内存负责管理JVM使用到的内存,比如创建对象、销毁对象。执行引擎将字节码文件中的指令解释称机器码,同时使用即使编译优化性能,包括即时编译器、解释器、垃圾回收器等。本地接口调用本地已经编译的方法,比如虚拟机中提供的C/C++的方法。
更多JVM结构规范可以在JVM手册找到详细介绍。
.class文件字节码文件中记录了一个类的详细信息,包括主次版本号、常量池、接口、字段、方法和属性信息,通过Jclasslib工具可以查看。

上图中为xyz.sl.Main类的基本信息,主版本号61代表了Java1.7。
如下面图片所示,常量14记录了test2方法的类名(xyz/sl/Main)、名字(test2)、参数列表(())和返回值(I)。Methodref_info常量并不直接记录这些字符串,而是记录这些字符串的引用 cp info #2 和 cp info #59 。
注意:cp info #2 和 cp info #59 也并非字符串引用,实际上是分别指向
Class_info和NameAndType_info。同Methodref_info一样,它们内部也是cp info #xx,但最终这些引用指向字符串常量Utf8_info。
Note
字符串记录信息的格式同安卓smali大同小异,每个信息常量分解方法也同dexlib2工具相似。
回到图片,查看编辑器14行,调用test1(),test1()调用test2(),所以在字节码文件中的字符串常量中可以找到他们的Methodref_info和Utf8_info。但是main方法中没有调用test1(),或者test1()中没有调用test2(),那么它们就不会出现在常量池中。第一种情况,两者都不会出现;第二种情况,test2不会出现。
如图可以看到test1()方法体对应的字节码,有点类似与汇编语言。iconst_1、istore_1等均是虚拟机指令,所有这11行指令,完全对应了test1()中的三行Java代码。指令的意思在JVM内存小节中解释。

和JVM结构一样,JVM指令也由规范文件给出,可以在JVM指令规范文件中查询。