JVM原理笔记

第一节 初识JVM
JVM的概念:JVM是Java Virtual Machine的简洁。意为Java虚拟机。


虚拟机
-指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统


有哪些虚拟机
-VMWare
-Visual Box
-JVM


VMWare或者Visual Box都是使用软件模拟物理CPU的指令集


JVM使用软件模拟Java字节码的指令集






JVM发展历史
1996年 SUN JDK 1.0 Classic VM
-纯解释运行,使用外挂进行JIT


1997年JDK1.1发布
-AWT、内部类、JDBC、RMI、反射


1998年 JDK1.2 Solaris Exact VM
-JIT 解释器混合
-Accurate Memory Management 精确内存管理,数据类型敏感
-提升的GC性能


2000年JDK1.3 Hotspot 作为默认虚拟机发布 加入JavaSound
2002年JDK1.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发布
    -延误项目推出到JDK8
    -G1
    -动态语言增强
    -64位系统中的压缩指针
    -NIO 2.0


2014年JDK8发布
    -Lambda表达式
    -语法增强 Java类型注解


2016年JDK9
    -模块化


使用最为广泛的JVM为HotSpot
HotSpot为Longview Technologies开发 被SUN收购
2006年 Java开源 并建立OpenJDK
    -HotSpot 成为Sun JDK和OpenJDK中所带的虚拟机
2008年Oracle收购BEA
    -得到JRockit VM
2010年Oracle 收购Sun
    -得到Hotspot
Oracle宣传在JDK8时整合JRockit和Hotspot,优势互补
    -在Hotspot基础上,移植JRockit优秀特性
----------------------------------------------------------------------
KVM
    -SUN发布
    -IOS Android前,广泛用于手机系统
CDC/CLDC HotSpot
    -手机、电子书、PDA等设备上建立统一的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文件类型
    -运行时数据
    -帧栈
    -虚拟机的启动
    -虚拟机的指令集


语法定义
-IfThenStatement:
    if(Expression)Statement          if(true){do sth;}


-ArgumentList:
    Argument                         add(a,b,c,d);
    ArgumentList,Argument


词法结构
    - \u + 4个16进制数字 表示UTF-16
    - 行终结符:CR,or LF,or CR LF。
    - 空白符
        空格 tab \t 换页 \f 行终结符
    - 注释
    - 标示符
    - 关键字
------------------------------------------------------------------------
- public static void 打印(){
-     System.out.println("中文方法哦");
- }
- public static void main(String[] args){
-     打印();
- }


-----------------------------------------------------------------------
词法结构
- Int
    0 2 0372 0xData_Cafe 1996 0x00_FF__00_FF
- Long
    0|0777L 0x100000000L 2_147_483_648L 0xC0B0L
- Float
    le1f 2.f .3f 0f 3.14f 6.022137e+23f
- Double
    le1 2. .3 0.0 3.14 1e-9d 1e137
- 操作
    += -= *= /= &= |= ^= %= <<= >>= >>>=


----------------------------------------------------------------------
哪些是合法的数字呢?
- 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;




类型和变量
-元类型
    byte short int long float char


-变量初始值
    boolean false
    char\u0000


-泛型
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);
    }
}
i1==3 but i2==4
v1.val==6 and v2.val==6
i1 i2为不同的变量
v1 v2为引用同一个实例
------------------------------------------------------------
Java内存模型
类加载链接过程
public static final abstract 的定义
异常
数组的使用


Java语言规范定义了什么是Java语言
Java语言和JVM相对独立
    -Groovy
    -Clojure
    -Scala
JVM主要定义二进制class文件和JVM指令集等


------------------------------------------------------------------
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);
}
----------------------------------------------------------------------
5
000000101
-6
原码:10000110
反码:11111001
补码:11111010
-1
原码:10000001
反码:11111110
补码:11111111
-----------------------------------------------------------------
为什么要用补码?
-计算0的表示:
0
正数:00000000
负数:10000000


0
正数:00000000


0
负数:1000000
反码:1111111
补码:0000000


-6+5
 11111010
+00000101
=11111111


-4+5
 11111100
+00000101
=00000001


-3+5
 11111101
+00000101
=00000010
-------------------------------------------------------------------
Float的表示与定义
-支持IEEE 754
$eeeeeeee mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
指数 8 尾数:23
e全0尾数附加位为0 否则尾数附加位为1
e全0 尾数附加位为0 否则尾数附加位为1
s*m*2^(e-127)


一些特殊的方法
-<clinit>
-<init>
-----------------------------------------------------------------
VM指令集
    -类型转化
    l2i
出栈入栈操作
    aload astore
运算
    iadd isub
流程控制
    ifeq ifne
函数调用
    invokevirtual invokeinterface invokespecial invokestatic
----------------------------------------------------------------------
JVM需要对Java Library提供以下支持:
-反射java.lang.reflect
-ClassLoader
-初始化class和interface
-安全相关 java.secuirty
-多线程
-弱引用


---------------------------------------------------------------------
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启动流程
------------------------------------------------------------------------------------------------
Java XXX--->装载配置--->根据配置寻找JVM.dll--->初始化JVM获得JNIEnv接口--->找到main方法并运行
             |                      |                        |
    |                      |                        |
根据当前路径和系统版本寻找          |                        |
jvm.cfg                             |                        |
                             JVM.dll为JVM主要实现            |
                JNIEnv为JVM接口,findClass等操作通过它实现
----------------------------------------------------------------------------------------------------
JVM基本结构
内存模型
编译和解释运行的概念


PC寄存器
-每个线程拥有一个PC寄存器
-在线程创建时 创建
-指向下一个指令的地址
-执行本地方法时,PC的值为undefined


-----------------------------------------------------------------------------------
方法区
-保存装载的类信息
    类型的常量池
    字段、方法信息
    方法字节码
-通常和永久区(Perm)关联在一起


JDK6时,String等常量信息置于方法
JDK7时,已经移动到了堆
------------------------------
Java堆
-和程序开发密切相关
-应用系统对象都保存在Java堆中
-所有线程共享Java堆
-对分代GC来说,堆也是分代的
-GC的主要工作区间
|------------------------------------|
|eden s0 s1 tenured                  |
|------------------------------------|
复制算法


Java栈
-线程私有
-栈由一系列帧组成(因此Java栈也叫做帧栈)
-帧保存一个方法的局部变量、操作数栈、常量池指针
-每一个方法调用创建一个帧,并压栈






Java栈-局部变量表 包含参数和局部变量
public class StackDemo{
    public static int runStatic(int i,long l,float f,Object o,byte b){
        return 0;
    } 


0 int int i
1 long long l
3 float float f
4 reference Object o
5 int byte b


--------
public int runInstance(char c,short s,boolean b){
    return 0;
}
}
0 reference this
1 int char c
2 int shourt s
3 int boolean b
----------------------
Java栈-函数调用组成帧栈
public static int runStatic(int i,long l,float f,Object o,byte b){
    return runStatic(i,l,f,o,b);
}


0 int int i
1 long long l
3 float float f
4 reference Object o
5 int byte b


0 int int i
1 long long l
3 float float f
4 reference Object o
5 int byte b


0 int int i
1 long long l
3 float float f
4 reference Object o
5 int byte b
注释:这是一个帧 省略:操作数栈 返回地址等
-----------------------------------------------
Java栈-操作数栈
-Java没有寄存器,所有参数传递使用操作数栈


public static int add(int a,int b){
    int c = 0;
    c = a + b;
    return c;
}


0:iconst_0  //压栈
1:istore_2  //弹出int,存放于局部变量2
2:iload_0   //把局部变量0压栈
3:il0ad_1   //局部变量1压栈
4:iadd      //弹出2个变量,求和,结果压栈
5:istore_2  //弹出结果,放于局部变量2
6:iload_2   //局部变量2压栈
7:ireturn   //返回
---------------------------------
Java栈-栈上分配
C++代码示例
class BcmBasicString{ ...}
public void method(){
    BcmBasicString* str = new BcmBasicString;
    ... delete str;
}
public void method(){
    BcmBasicString str;
    ...
}
-小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上
-直接分配在栈上,可以自动回收,减轻GC压力
-大对象或者逃逸对象无法栈上分配




-----------------------------
解释运行
-解释执行以解释方式运行字节码
-解释执行的意思是:读一句执行一句


编译运行(JIT)
-将字节码编译成机器码
-直接执行机器码
-运行时编译
-编译后性能有数量级的提升


----------------------知己知彼 百战不殆--------------------------


























































































































































































































































































































































































































































































































































































































JVM种类
JVM规范

你可能感兴趣的:(JVM原理笔记)