指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统
比如它们模拟的cpu、硬盘、内存,等都是现实存在的,能够在现实中找到对应的案例的。
JVM模拟的对象是现实中没有的,现实中没有任何一个计算机能够运行Java字节码,单纯从从软件上做的一个设计,来模拟一个硬件的行为,比如jvm运行的的是java字节码指令集,为了设计上的精简,我们知道正常的cpu中有若干个寄存器,jvm中除了pc寄存器外,其他的寄存器都做了裁剪,因为寄存器的主要功能是加快数据访问的速度,因为在jvm中是纯粹用软件模拟的,速度使用寄存器后并不会有很好的提升,并且引入寄存器后,也为jvm的设计以及实现带来很大的困难,所以把这些功能去掉了。综上,jvm是一个被定制过的现实中不存在的计算机。
纯解释运行,使用外挂进行JIT,没有内置的即时编译的模块,一旦开启外挂,解释运行的功能就没有了。
Classic VM生命周期比较长,在1.3 、1.4的时候才被淘汰
-AWT、内部类、JDBC、RMI、反射
JIT 解释器混合
Accurate Memory Management 精确内存管理,数据类型敏感
提升的GC性能
JDK1.2开始 称为Java 2
J2SE J2EE J2ME 的出现
加入Swing Collections
Solaris Exact VM生命周期比较短。
加入JavaSound加入了一些声音上的api
Assert 正则表达式 NIO IPV6 日志API 加密类库
泛型
注解
装箱
枚举
可变长的参数
Foreach循环
脚本语言支持
JDBC 4.0
Java编译器 API(开放了这个API)
延误项目推出到JDK8
G1(全新的gc收集器)
动态语言增强(动态语言的火热)
64位系统中的压缩指针
NIO 2.0
Lambda表达式(模拟了函数式编程)
语法增强 Java类型注解
模块化
HotSpot 成为Sun JDK和OpenJDK中所带的虚拟机
得到JRockit VM
得到Hotspot
在Hotspot基础上,移植JRockit优秀特性
推测:JRockit在不久的将来会退出历史舞台,但是HotSpot会深受JRockit的影响。
SUN发布
IOS Android前,广泛用于手机系统
手机、电子书、PDA等设备上建立统一的Java编程接口
J2ME的重要组成部分
IBM内部
兼容于JDK 1.5和JDK 1.6的Java程序运行平台
与Oracle关系恶劣 退出JCP ,Java社区的分裂
OpenJDK出现后,受到挑战 2011年 退役
没有大规模商用经历
对Android的发展有积极作用
BEA
if ( Expression ) Statement
if(true){do sth;}
Argument
ArgumentList , Argument
add(a,b,c,d);
\u + 4个16进制数字 表示UTF-16
行终结符: CR, or LF, or CR LF.
空白符
空格 tab \t 换页 \f 行终结符
注释
标识符
关键字
//标识符:标识符字符串不能使关键字或者布尔值或者null
Identifier: IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
//标识符串:java字符
IdentifierChars: JavaLetter IdentifierChars JavaLetterOrDigit
//java字符:任何一个unicode
JavaLetter: any Unicode character that is a Java letter (see below)
//
JavaLetterOrDigit: any Unicode character that is a Java letter-or-digit (see below)
public static void 打印(){
System.out.println("中文方法哦");
}
public static void main(String[] args) {
打印();
}
有意思的是,代码中有中文
在jdk1.7中一个比较大的改变是允许有下划线,好处是当数字比较大的时候看的比较清楚一些。
private int a=0xDada_Cafe;
private float b=0x1.fffffeP+127f;
private float c=1996;
private float d=1996.3;
private int f=9999e2;
private double g=33e2;
private float h=0x1.fffep-12f;
private float i=1.fffep-12f;
private long p=0b1_1_1_0_1;
private long q=0b1_1_1_0_2;
class Value { int val; }
class Test {
public static void main(String[] args) {
int i1 = 3;
int i2 = i1;
i2 = 4;
System.out.print("i1==" + i1);
System.out.println(" but i2==" + i2);
Value v1 = new Value();
v1.val = 5;
Value v2 = v1;
v2.val = 6;
System.out.print("v1.val==" + v1.val);
System.out.println(" and v2.val==" + v2.val);
}
}
i13 but i24
v1.val6 and v2.val6
i1 i2为不同的变量
v1 v2为引用同一个实例
Java内存模型
类加载链接的过程
public static final abstract的定义
异常
数组的使用
…….
Java语言规范定义了什么是Java语言
Java语言和JVM相对独立
符合JVM规范的就能够在JVM上运行,比如:
Groovy
Clojure
Scala
JVM主要定义二进制class文件和JVM指令集等
Class 文件格式
数字的内部表示和存储
Byte -128 to 127 (-27 to 27 - 1)
returnAddress 数据类型定义
指向操作码的指针。不对应Java数据类型,不能在运行时修改。Finally实现需要
定义PC
堆
栈
方法区
int a=-6;
//因为整数有32位,所以进行32次循环。
for(int i=0;i<32;i++){
//0x80000000表示最高位为1的数字,所以a & 0x80000000只有一位是1,
//第一次i=0,就是把a的第一位取出来,无符号右移(31-i)位。
//依次循环,将每一位打印出来
int t=(a & 0x80000000>>>i)>>>(31-i);
System.out.print(t);
}
5
00000101
-6
原码: 10000110
反码: 11111001
补码: 11111010
-1
原码: 10000001
反码: 11111110
补码: 11111111
0是一个比较特殊的数字,既不属于正数,也不属于负数
计算0的表示:
0
正数:00000000
负数:10000000
0
正数:00000000
0
负数:10000000
反码:11111111
补码:00000000
看到这里补码的好处是为了没有歧义的表示零
-6+5
11111010
+ 00000101
= 11111111
-4+5
11111100
+ 00000101
= 00000001
-3+5
11111101
+ 00000101
= 00000010
看到这里,补码还有一个好处就是方便的计算两个数字之和(两个补码之和,符号位直接参与运算,得到的记过就是正确的结果。如果是源码做计算,符号位参与运算得不到正确的结果。),当然减法是一个特殊的加法。
支持 IEEE 754
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
s符号位 eeeeeeee 指数:8 mmmmmmmmmmmmmmmmmmmmmmm 尾数:23
e全0 尾数附加位为0 否则尾数附加位为1,所以这里的尾数看似是23位,实质上是24位。
表达式
s*m*2^(e-127)
m指的是后面的23位
-5
1 10000001 01000000000000000000000
-1*2^(129-127)*(2^0+2^-2)
clinit 类的初始化方法
init 实例的初始化方法
因为这些功能没有办法通过java语言本身支持,所以通过JVM实现。
源码到JVM指令的对应格式
Javap 反编译
JVM反汇编的格式:
<index> <opcode> [ <operand1> [ <operand2>... ]] [<comment>]
索引(偏移量) 操作码(±*/入站出站) 注解
void spin() {
int i;
for (i = 0; i < 100; i++) { ;
// Loop body is empty
}
}
0 iconst_0 // Push int constant 0
1 istore_1 // Store into local variable 1 (i=0)
2 goto 8 // First time through don't increment
5 iinc 1 1 // Increment local variable 1 by 1 (i++)
8 iload_1 // Push local variable 1 (i)
9 bipush 100 // Push int constant 100
11 if_icmplt 5 // Compare and loop if less than (i < 100)
14 return // Return void when done
在JVM中直接执行的是JVM指令代码(如上)。