什么是 JVM?
A **J**ava **V**irtual **M**achine(JVM)is an abstract computing machine that enables a computer to run a Java program – wikipedia.org
JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的 – baike.baidu.com
为什么要有 JVM?
跨平台性
JVM 的存在,使得 Java 程序 能够轻易地在多平台上移植,基本上脱离了对硬件的依赖性(这也满足了 David Parnas 的 “信息隐藏” 准则)
多语言性
因为底层 JIT 编译优化、GC、JUC 对多线程并发编程的支持,以及社区中海量成熟的库 等优点,使得 很多语言 都开发出可运行在 JVM 上的版本
同时,多语言混合编程成为一种趋势,在需要快速开发、灵活部署 和 针对特定问题的 DSL 等场景下,选择恰当的 JVM-hosted language,可以最大化原有代码的价值
那么,在日常的开发过程中,究竟应该如何运用这些 遥不可及的 JVM 知识,来逐步提高实际编程水平呢? 上下而求索了一番后,找到了以下几个层面作为出发点
编码层面
递归 vs. 尾递归
循环调用
def inc(i: Int): Int = i + 1
# 10 亿次 for 循环调用
0: aload_0 |从局部变量 0 中装载引用类型值
1: getfield #29 // Field i$1:Lscala/runtime/IntRef; |从对象中获取字段
4: getstatic #33 // Field com/yuzhouwan/jit/Inc$.MODULE$:Lcom/yuzhouwan/jit/Inc$; |从类中获取静态字段
7: aload_0 |从局部变量 0 中装载引用类型值
8: getfield #29 // Field i$1:Lscala/runtime/IntRef; |从对象中获取字段
11: getfield #38 // Field scala/runtime/IntRef.elem:I |从对象中获取字段
14: invokevirtual #42 // Method com/yuzhouwan/jit/Inc$.inc:(I)I |运行时按照对象的类来调用实例方法
17: putfield #38 // Field scala/runtime/IntRef.elem:I |设置对象中字段的值
20: return |从方法中返回,返回值为 void
# 被调用的累加方法
0: iload_1 |从局部变量 1 中装载 int 类型值入栈
1: iconst_1 |1(int) 值入栈
2: iadd |将栈顶两 int 类型数相加,结果入栈
3: ireturn |返回 int 类型值
10 亿次循环,大约 4014 ms
递归
def rec(i: Int): Int = {
if (i == 1) return 1
rec(i - 1) + 1 // change 1 to i, then counting...
}
0: iload_1 |从局部变量 1 中装载 int 类型值
1: iconst_1 |1(int) 值入栈
2: if_icmpne 7 |若栈顶两 int 类型值前小于等于后则跳转
5: iconst_1 |1(int) 值入栈
6: ireturn |返回 int 类型值
7: aload_0 |从局部变量 0 中装载引用类型值
8: iload_1 |从局部变量 1 中装载 int 类型值