1:JVM基础知识
-
什么是JVM
jvm虚拟机大的范围包括classLoader、字节码解释器、即时编译器和执行引擎,本身就是一个虚拟的机器,有自己的cpu有自己的内存管理、汇编语言等,是一个跨语言的平台,理论上只要是class文件 就能执行。
JVM是一种规范,常见jvm实现有我们常用hotSpot(oracle官方)。淘宝有淘宝的taobaoVM
等等。 比如还有azul zing 垃圾回收特别快。
jvm<jre<jdk
jvm 运行class那些
jre 运行时环境包含一些核心类库
jdk 包含开发的包和工具 -
常见的JVM
常见jvm实现有我们常用hotSpot(oracle官方)。淘宝有淘宝的taobaoVM
等等。 比如还有azul zing 垃圾回收特别快。
2:ClassFileFormat
class文件
class文件是二进制字节流
16进制文件打开 cofe baby开头
数据类型: u1 u2 u4 u8和_info (表类型)
_info的来源是hotspot源码中的写法
●查看16进制格式的ClassFile
sublime / notepad /
IDEA插件 - BinEd
●有很多可以观察ByteCode的方法:
javap
JBE-可以直接修改
JClassLib - IDEA插件之一
●classfile构成
包括版本号、jdk版本号、常量池计数、接口计数、方法计数、属性计数、哪些属性等等。。
3:类编译-加载-初始化
1.加载过程
1.loading 类加载器把class文件load到内存
2.linking
1.verfication 校验class文件,校验文件是否符合规定
2.preparation 静态成员变量赋默认值
3.resolution 将类、方法、属性等符号引用解析为直接引用,常量池的各种符号引用解析为指针、偏移量等内存地址的直接引用
3.initializing
1.调用类初始化代码,给静态成员变量赋初始值
类加载器
jvm有一个类加载器的层次,类加载器是一个普通的class,分别加载不同的class,所有class都是被类加载器加载到内存。
想看一个类被哪个classLoader load到内存的,用哪个类的class对象.getClaaaLoader()方法。
一个class文件生产两个文件,一个是class二进制码的内容,一个是生成一个对应的class类的对象。
不同的类加载器加载不同的class:
找不到类加载器的时候就会抛异常 classNotFound
类加载过程:
先从下往上,如果从缓存中找到,就下载,找不到就从上往下找,最后找不到就会抛异常 classNotFound
自定义类加载器
1.extends ClassLoader
2.重写findClass()方法
为什么使用双亲委派机制?
jvm是按需动态加载,为了安全因素考虑,因为不是说任何一个class都能自由的load到内存,比如我们自定义一个java.lang.String,当要求一个我们自定义的classLoad加载这个自定义的String.class时
,会从下往上查,如果已经加载过了就会直接返回。
jvm编译
混合模式
混合使用 解释器 + JIT 热点代码编译器
起始阶段采用解释执行
热点代码检测:
多次被调用的方法(每个方法都有一个方法计数器:检测方法执行频率)
多次被调用的循环(循环计数器:检测循环执行频率)
进行编译
解释模式:启动很快 执行稍慢
编译模式:执行很快,启动稍慢