深入JVM内核—原理、诊断与优化之:初识JVM(一)
JVM概念
-
JVM是Java Virtual Machine的简称.意为Java虚拟机
-
虚拟机
指通过软件模拟的具有完整硬件系统功能的,运行在一个完全隔离环境中的完整计算机系统
-
有哪些虚拟机
-
VMWare
-
Visual Box
-
JVM
-
-
VMWare或者Visual Box都是使用软件模拟物理CPU指令集
-
JVM使用软件模拟Java字节码的指令集
Java和JVM的历史
-
1996年SUN JDK 1.0 Classic VM
- 纯解释运行,使用外挂进行JIT
-
1997年 JDK 1.1 发布
- AWT,内部类,JDBC,RMI,反射
-
1998年 JDK 1.2 Solaris Exact VM
-
JIT 解释器混合
-
Accurate Memory Management 精确内存管理,数据类型敏感
-
提升了GC性能
-
JDK 1.2 开始成为Java2 J2SE J2EE J2ME出现 加入Swing Collections
-
-
2000年 JDK 1.3 Hotspot 作为默认虚拟机发布
- 加入JavaSound
-
2002年 JDK 1.4 Classic VM 退出历史舞台
-
Assert 正则表达式 NIO IPV6 日志API 加密类库
-
2004年发布 JDK1.5 即JDK5,J2SE 5,Java 5
-
泛型
-
注解
-
装箱
-
枚举
-
可变长的参数
-
Foreach循环
-
-
JDK1.6 JDK6
-
脚本语言支持
-
JDBC 4.0
-
Java编译器 API
-
-
2011年 JDK7发布
-
由于JDK7加入内容太多,项目规划出现问题直到2011年才发布,延误项目推出到JDK8
-
G1垃圾回收器
-
动态语言增强
-
64位系统中的压缩指针
-
NIO 2.0
-
-
2014年 JDK8 发布
-
Lambda表达式
-
Stream
-
语法增强 Java类型注解
-
-
2016年 JDK9
-
模块化 Java + REPL = jshell
-
简化进程API
-
轻量化JSON API
-
货币API
-
改善竞争锁
-
分割代码缓存区
-
Smart Java Compilation项目
-
大事记
-
使用最为广泛的JVM为HotSpot
-
HotSpot为Longview Technologies开发 被SUN收购
-
2006年Java开源并建立OpenJDK
- HotSpot成为SUN JDK和Open JDK中所带的虚拟机
-
2008年Oracle收购BEA
- 得到JRockit VM
-
2010年Oracle收购SUN
- 得到Hotspot
-
Oracle宣布在JDK8时整合JRockit和Hotspot,优势互补
- 在Hotspot基础上,移植JRockit优秀特性
各式JVM
-
KVM
-
Sun发布
-
IOS Android前,广泛用于手机系统
-
-
CDC/CLDC HotSpot
-
手机,电子书,Pad等电子设备上建立统一的Java编程接口
-
J2ME的重要组成部分
-
-
JRockit
- BEA
-
IBM J9 VM
- IBM内部
-
Apache Harmony
-
兼容与JDK 1.5和JDK 1.6的Java程序运行平台
-
与Oracle关系恶劣 退出JCP Java社区的分裂
-
OpenJDK出现后,受到挑战,2011年退役
-
没有大规模商用经历
-
对Android的发展有积极作用
-
规范
-
Java语言规范
-
语法
-
变量
-
类型
-
文法
-
-
JVM规范
-
Class文件类型
-
运行时数据
-
帧栈
-
虚拟机的启动
-
虚拟机的指令集
-
Java语言规范
-
语法定义
-
IfThenStatement:
if( Expression ) Statement
-
ArgumentList:
Argument
ArgumentList,Argument
-
-
词法结构
-
\u + 4个16进制数字 表示UTF-16
-
行终结符:CR or LF,or CR LF
-
空白符
空格 tab \t 换页 \f 行终结符
-
注释
-
标识符(变量、类、方法等命名的符号)
-
关键字
-
int
0 2 0372 0xData_Cafe 1996 0x00_FF__00_FF
从JDK 1.7开始允许使用下划线分割数字
-
long
0l 0777L 0x1000000000L 2_17_483_68L 0xC0B0L
-
float
1e1f 2.f .3f 0f 3.1444f 6.022137e+23f
-
double
1e1 2. .3 0.0 3.14 1e-9d 1e137
-
操作
+= -= *= /= &= |= ^= %= <<= >>= >>>=
-
-
类型和变量
-
元类型
byte short int long float char
-
变量初始化
boolean false
char \u0000
-
泛型
-
JVM规范
-
Java语言规范定义了什么是Java语言
-
Java语言和JVM行对独立
-
Gloovy
-
Clojure
-
Scala
-
-
JVM主要定义二进制class文件和JVM指令集
-
Class文件格式
-
数字的内部表示和存储
- byte -128 to 127 (-2^7 to 2^7 -1)
-
returnAddress 数据类型定义
- 指向操作字节码的指针.不对应Java数据类型,不能在运行时修改.Finally实现需要
-
定义PC(指令集寄存器)
-
堆
-
栈
-
方法区
-
整数的表达
-
原码:第一位为符号位(0位正数,1为负数)
-
反码:符号位不动,原码取反
-
负数补码:符号位不动,反码加1
-
正数补码:和原码相同
-
打印整数的二进制表示
-
int a = -6;
for(int i=0;i<32;i++){
int t = (a & 0x80000000 >>> i)>>>(31-i);
System.out.print(t);
}
-
为什么要用补码
- 计算0的表示
按照0是正数:00000000,负数:10000000,补码都为00000000没有歧义
计算加分法直接用补码相加就可以了
-
float的表示与定义
-
支持IEEE 754
-
s eeeeeeee mmmmmmmmmmmmmmmmmmmmm
s为符号位,e为指数位(8位),m为尾数(23位)
-
e全0 尾数附加位为0 否则尾数附加位为1
-
sm2^(e-127)
-
-5
1100000010100000000000000000000000
-12^(129-127)(2^0+2^-2)
-
一些特殊的方法
-
<clint>
类的初始化方法,只有在类初始化的时候调用一次
-
<init>
每初始化一个实例调用一次
-
-
VM指令集
-
类型转换
l2i(long-->int)
-
出栈入栈操作
aload astore
-
运算
iadd isub
-
流程控制
ifeq ifne
-
函数调用
invokevirtual invokeinterface invokespecial invokestatic
-
-
JVM需要对Java Library提供以下支持
-
反射 java.lang.reflect
-
ClassLoader
-
初始化class和interface
-
安全相关 java.security
-
多线程
-
弱引用
-
-
JVM的编译
-
源码到JVM指令对应格式
-
javap(反编译器)
-
JVM反汇编格式
<index><opcode>[<operand1>[operand2...]][<comment>] (index:索引,opcode:操作码,operand:操作数,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 throught 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