导图社区 JVM梳理
这是一篇关于JVM梳理的思维导图,包括类加载机制、JVM内存结构、垃圾收集器、Java内存模型与线程。
编辑于2021-11-12 23:06:18JVM梳理
类加载机制
什么是类加载
定义:加载.class文件中二进制流文件,最终生成堆区的 Class对象,用于封装方法区的数据结构
加载.class的方式
本地系统
网络下载
从zip,jar等归档文件中
从专有数据库中
java源文件编译成
加载的时机
预加载
懒加载(使用时再加载)
报错:linkageError
类的生命周期
加载
加载类生成cLass对象,方法区运行的结构
验证
文件格式验证
以0xCAFEBYBE开头
主次版本号是否支持
常量池类型是否支持
元数据验证
是否符号java语义规范
字节码的描述语义分析
字节码验证
通过数据流和控制流 语义分析
符号引用验证
符号引用是否能够解析对
准备
为静态变量分配内存,并将其初始化化为默认值
是0,null之类的默认值
解析
将符号引用转换成直接引用
接口
字段
类方法
接口方法
方法类型
方法句柄
调用点限定符
初始化
定义:为类的静态变量赋予正确的初始值
方式
声明类变量
静态代码块为类变量
初始化时机
创建类的实例
访问某个类或接口的静态变量或赋值
调用类的静态方法
反射
初始化某个类的子类
jvm标明为启动类的类
使用
卸载
system.exit()
正常结束退出
异常或错误而终止
操作系统kill
类加载器
启动类加载器
jre\lib下的
扩展类加载器
jre\lib\ext下
应用加载器
类的加载
三种方式
命令行启动应用时jvm初始化加载
Class.forname
ClassLoader.loadClass()
双亲委派
先给父类加载器加载,AppClassLoader 给ExtclassLoader,再给BootStrapClassloader,如果父类加载不了,再自己来
意义
防止内存中出现多份同样的字节码
保障java程序安全稳定运行
自定义类加载器
可以尝试打破双亲委派
如tomcat的类加载、pandola的类加载器
可以是要分模块加载,防止类冲突
JVM内存结构
堆内存
作用:所有对象实例的内存分配
老年代
年轻代
eden空间 8:1:1
from survivor空间
to survivor空间
方法区
存储jvm加载的类信息、常量、静态变量、即时编译后的代码等数据
栈
程序计数器
JVM栈
局部变量表、操作数、动态链接、方法出口等
本地方法栈
jvm使用到的native方法
outOfMemoryError
OutOfMemoryError:Java heap space
对象不能分配到堆内存中
OutOfMemoryError:Perm space
类和方法不能加载到老年代
jvm栈
native栈
垃圾收集器
对象存活判断
引用计数
无法解决循环引用
可达性分析
GC roots的定义
虚拟机栈中引用的对下
方法区中静态属性的引用对象
方法区中常量引用的对象
本地方法栈中jni应用的对象
再谈引用
强引用
软引用
内存泄露时回收
softRefrence
弱引用
gc时回收
weakreference
虚引用
plantomreference
很少用
生存还是死亡
finalize()
对象需要经历两次标记
第一标记并进行一次筛选,是否需要执行一次finalize()
执行finalize 方法 引用其他方法,可不死
回收方法区
废弃的常量
没有改常量的引用
无用的类 回收
所有实例回收
类的classloader 已经回收
无任何地方引用
垃圾收集算法
标记-清除
一般用于老年代
效率不高
内存碎片
标记-整理
用于老年代
复制
年轻代
分代收集
垃圾收集器
Serial收集器
古老、稳定、效率高
单线程
新生代复制算法
老年代用标记-整理算法
与serial_Old配合
stop the world
ParNew收集器
Serial的多线程版本
新生代并行
复制算法
老年代串行
标记-整理算法
与serial_Old配合
Parallel收集器
类似于ParNew
更加关注吞吐量
收集系统的性能,动态调整停顿时间或吞吐量
Parallel Old收集器
多线程
老年代
标记-整理算法
与paralle收集器配合
cms收集器
最短停顿时间的收集器
比较注重用户体验
标记-清除算法
老年代
步骤
初始标记
stop the world
很快,Gcroot下面的第一级对象
并发标记
重新标记
stop the world
并发清楚
优缺点
优点
并发收集、低停顿
缺点
产生大量空间碎片
浮动垃圾
并发阶段降低吞吐量
G1
两大关注点
空间整合
标记-整理
可预测的低停顿时间
步骤
初始标记
Gc roots 下第一级 对象
stop the world
并发标记
最终标记
stop the world
多线程
筛选回收
stop the world
多线程
内存分配与回收策略
对象优先在eden分配
8:1:1,1:2
大对象直接进入老年代
长期存活的对象进入老年代
动态对象的年龄判定
空间分配担保
Java 内存模型与线程
处理器-高速缓存-主内存
存在一致性协议
Java内存模型
线程-工作内存-save or load -主内存
lock
unlock
read
load
use
assign
store
write
对于volatile型变量的特殊规则
保证变量对所有线程的可见性
禁止指令重排序优化
对long 和double型变量的特殊
对于32位系统允许分两次读写
原子性不足
原子性、可见性、有序性
先行发生原则
happen-before
java 与线程
线程的实现
使用内核线程实现
轻量级进程(Lwp)
Java的的线程实现
使用用户线程实现
混合实现
线程调度
协同式线程调度
抢占式调度
状态
新建
运行
阻塞
等待锁或资源
无限期等待
Object.wait()
Thread.join
LookSupport.park()
有限期等待
sleep
wait(1s)
thread.join(1s)
结束