《深入理解Java虚拟机》读书笔记
2022-11-22 12:54:04 0 举报
AI智能生成
周志明深入理解Java虚拟机
作者其他创作
大纲/内容
第一部分 走进Java
虚拟机实例
一个JAVA程序对应一个虚拟机实例,以main()为开始
内部线程分类
守护线程
非守护线程
虚拟机的退出
所有非守护线程终止
调用exit()方法
虚拟机体系结构
创建新线程
PC寄存器
栈
分类
JAVA栈
本地方法栈
组成
栈帧
JVM的类型
Server VM
Client VM
JVM的工作模式
-Xint
解释模式
-Xcomp
编译模式
-Xmixed
混合模式
类装载子系统
类装载顺序
装载
连接
验证
准备
解析
初始化
第二部分 自动内存管理机制
第1章 运行时数据区
方法区
运行时常量池
字段信息
方法信息
类(静态)变量
指向ClassLoader类的引用
指向Class类的引用
堆
程序计数器
PC寄存器
虚拟机栈
本地方法栈
第2章 HotSpot虚拟机对象探秘
2.1 对象的创建
分配方式
指针碰撞
空闲列表
2.2 对象的内存布局
对象头
自身运行时数据
哈希码
GC分代年龄
锁状态标识
自身持有的锁
偏向线程ID
偏向时间戳
类型指针
实例数据
对齐填充
起占位符的作用
2.3 对象的访问定位
使用句柄
Java堆中划分出一块内存作为句柄池
直接指针
第3章 垃圾收集器与内存分配策略
3.2 对象已死吗?
引用计数算法
弊端:循环引用
可达性算法
GC Roots
虚拟机栈中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
对象引用
JDK1.2之后扩充
强引用
弱引用
软引用
虚引用
生存还是死亡
回收方法区
3.3 垃圾收集算法
标记-清除算法
缺点:耗时,耗空间
标记、清除效率低
产生大量不连续内存碎片
复制算法
效率高,但是内存缩小为原来一半,空间代价过大
标记-整理算法
对老年代进行标记整理
分代收集算法
新生代
复制算法
老年代
标记清除
标记整理
3.4 Hotspot算法实现
枚举根节点
安全点
GC时所有的线程需要中断。程序可以GC的特殊点。
抢先式中断
主动式中断
安全区域
GC安全的区域
3.5 垃圾收集器
serial收集器
新生代,串行,单线程,复制算法
ParNew收集器
新生代,并行,serial的多线程版本,复制算法
仅用于新生代GC
parallel scavengel收集器
新生代,多线程,复制算法;达到可控的吞吐量
serial old收集器
老年代,串行,单线程,标记整理算法
parallel old收集器
老年代,并行,多线程,标记整理算法
cms收集器
老年代,多线程并发,标记清除算法
初始标记
并发标记
重新标记
STW
并发清除
G1收集器
优点
并行并发
分代收集
空间整合
可预测的停顿
运行步骤
初始标记
STW
并发标记
最终标记
短暂STW
筛选回收
3.6 内存分配与回收策略
对象优先在Eden分配
大对象直接进入老年代
长期存活的对象将进入老年代
动态对象年龄判定
空间分配担保
第4章 虚拟机性能监控与故障处理工具
4.2 jdk的命令行工具
jps
jstat
jinfo
jmap
jhat
jstack
hsdis
4.3 jdk的可视化工具
jsonsole
visualvm
第5章 调优案例分析与实战
第三部分 虚拟机执行子系统
第6章 类文件结构
6.3 class类的文件结构
类C伪结构
无符号数
u1/u2/u4/u8
表
_info结尾
6.3.1魔数与Class文件的版本
u4:magic_number
0xCAFEBABE(cafe babe)
版本号
u2:minor_version
u2:major_version
版本号从45开始,向前兼容
6.3.2常量池
u2:constant_pool_count
cp_info:constant_pool
主要存放
字面量
文本字符串、final常量
符号引用
类和接口的全限定名
字段的名称和描述符
方法的名称和描述符
6.3.3访问日志
u2:access_flags
6.3.4类索引、父类索引与接口索引集合
u2:this_class
u2:super_class
u2:interfaces_count
u2:interfaces
6.3.5字段表集合
u2:fields_count
field_info:fields
6.3.6方法表集合
u2:methods_count
method_info:methods
6.3.7属性表集合
u2:attributes_count
attribute_info:attributes
6.4字节码指令简介
6.4.1字节码与数据类型
数据类型
基本类型
数值类型
浮点类型
float
double
整数类型
byte
short
int
long
char
boolean
returnAddress
引用类型
类
接口
数组
方法参数传递
按值传递
按引用传递
对象做参数
6.4.2加载和存储指令
6.4.3运算指令
6.4.4类型转换指令
6.4.5对象创建与访问指令
6.4.6操作数栈管理指令
6.4.7控制转移指令
6.4.8方法调用和返回指令
6.4.9异步处理指令
6.4.10同步指令
6.5公有设计和私有实现
6.6class文件结构的发展
第7章 虚拟机类加载机制
7.2类加载的时机
有且只有5种情况立即“初始化”类
new对象时;调用类的静态字段或者方法时
对类反射调用时
初始化类而其父类未初始化时,先初始化父类
虚拟机启动时,初始化主类(包含main方法的类)
JDK1.7动态语言支持,REF_*句柄对应的类
7.3类加载的过程
类的生命周期7阶段
加载
3件事
获取二进制字节流
ZIP读取
网络读取:Applet
运行时计算生成:反射
其他文件生成:JSP
数据库读取:中间件服务器
二进制字节流转化为方法区数据结构
内存中生成java.lang.Class对象
数组类加载
数组类本身由java虚拟机直接创建,
数组类的元素类型由类加载器创建
数组类创建3原则
数组类是引用类型,在类加载器的类名空间上被标识
数组类不是引用类型(int[]),标记为与引导类加载器关联
数组类的可见性与其组件类型一致,组件为非引用类型,默认public
连接
验证
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
在方法区中为类变量(static、final等修饰)分配内存和设置初始值
(准备阶段只赋默认值如0等)
解析
是符号引用替换为直接引用的过程
符号引用
不一定已加载到内存
直接引用
一定已加载到内存
解析动作
类或接口的解析
字段解析
类方法解析
接口方法解析
初始化
真正开始执行类中定义的Java程序代码(字节码)
执行类构造器<clinit()>方法
使用
卸载
7.4类加载器
源起
“通过一个类的全限定名来获取描述此类的二进制字节流”
这个动作在Java虚拟机外部实现
实现这个动作的代码模块称为“类加载器”
类与类加载器
每一个类加载器都有一个独立的类命名空间
双亲委派模型
类加载器种类
启动类加载器
BootStrap Classloader
BootStrap Classloader
C++实现,是虚拟机自身的一部分
扩展类加载器
Extension ClassLoader
Java实现,独立于虚拟机之外
并且全部继承自抽象类:java.lang,ClassLoader
应用程序类加载器
Application ClassLoader
破坏双亲委派模型
第8章 虚拟机字节码执行引擎
8.2运行时栈帧结构
局部变量表
操作数栈
动态连接
方法返回地址
返回信息
8.3方法调用
8.4基于栈的字节码解释执行引擎
第9章 类加载机制执行子系统的案例与实战
第四部分 程序编译与代码优化
第10章 早期(编译期)优化
10.2Javac编译器
10.3Java语法糖的味道
10.4插入式注解处理器
第11章 晚期(运行期)优化
第五部分 高效并发
第12章 Java内存模型与线程
12.2硬件的效率与一致性
12.3Java内存模型
主内存与工作内存
内存间交互操作
八种操作
lock锁定
unlock解锁
read读取
load载入
use使用
assign赋值
store存储
write写入
八条规则
对于volatile型变量的特殊规则
对于long和double型变量的特殊规则
原子性、可见性和有序性
先行发生原则
12.4Java与线程
线程的实现
使用内核线程实现
使用用户线程实现
使用用户线程加轻量级进程混合实现
Java线程调度
协同式
抢占式
状态转换
新建
运行
无限期等待
限期等待
阻塞
结束
第13章 线程安全
13.2线程安全
Java语言中的线程安全
共享数据分类
不可变
绝对线程安全
相对线程安全
线程兼容
线程对立
线程安全的实现方法
互斥同步
非阻塞同步
无同步方案
13.3锁优化
自旋锁与自适应自旋
锁消除
锁粗化
轻量级锁
偏向锁
0 条评论
下一页