JVM模型与JMM模型
2023-12-26 09:27:20 33 举报
JVM模型与JMM模型
作者其他创作
大纲/内容
mac os
load/write
CPU 3
每经过一次年轻代GC,年龄+1,当年龄等于设置值(默认15),则从survior转到到老年代
CPU 2
类库
用户线程2
局部变量表
3、重新标记
Minor GC确保成功
类加载器规则
G1过程
class二进制流
ParNew
堆
CPU 0
1、初始标记
特点:serial的多线程版本优点:在多CPU下,垃圾收集更快缺点:在单cpu,浪费线程资源,收集慢场景:适合Server模式
连接
7
用户线程3
4、并发清除垃圾对象
老年代1、存活对象多2、内存大,没有额外空间
surivor区
jdk和jre
Parallel Old
4、并发清除
JMM是一个规范,解决多线程在访问共享变量,因 本地工作内存数据不一致(可见性)、编译器指令重排(有序性),处理器乱序执行代码(原子性)而引发的问题
使用
groovy
查看jvm参数设置是否允许担保失败
针对重写场景1、调用实际类型的方法
Object obj = new Object()
方法返回地址
3、标记第二步并发时工作线程产生新的可达对象
1、类加载器通过类名加载class2、将class信息,静态变量、常量加载到方法区3、创建Class对象指向 class信息内存地址
用户线程4
字节码指令的执行,涉及局部变量表和操作数栈数据的出入
2
5、空间分配担保
方法区
基本数据类型变量存储真正的值引用类型变量存储是一个地址(指向堆中的某个实例数据)
2、并发标记
Minor GC
用户线程1
6
Parallel Scavenge
其他二进制流
其他语言
特点:1、单线程2、GC时暂停工作线程优点:1、单线程实现简单高效,适合单CPU缺点:1、暂停工作线程导致短暂停顿场景:1、适合Client模式
回收线程1
原子性
CPU 1
5
float
栈帧1
复制
APP Classloader
Object3
老年代
检查老年代最大连续空间>新生代所有对象空间之和?
.class本地文件
类加载器的委托对于同一个类只能加载一次
machine
字段说明
4、筛选回收
jdk
方法已确定,需确定实际类
可回收
其他信息
linux jvm
N
windows
类信息(包括)静态变量常量JIT编译后的代码
对象实例
jvm运行时内存分区
栈帧n
java编译器
G1+G1
类信息
方法调用
ParNew+CMS
system os
大字符串或者大数组对象,所占空间大于设置值时,则直接分配到老年代,避免分配在年轻代导致Eden和Survior发生大量复制
complier
特点:1、Parallel Scavenge的老年代版本
1、在类加载的解析阶段,将静态方法、私有方法、构造方法、父类方法的符号引用转为直接引用
访问标志
类加载
魔数
自定义Classloader
Full GC
Java内存模型(JMM)
类只能看到由其类加载器的委托加载的其他类其类加载器的委托是类的加载器及其所有父类加载器
工作内存
常量池
改进
3
可见性
标记-整理
Minor GC当Eden区满或者创建对象时Eden区剩余空间不够时触发MinorGC
Parallel Scavenge+ Parallel Old
解析
动态年龄
int
以最小停顿时间为目标优点:1、并发手机停顿时间短缺点:1、并发占用部分cpu资源导致工作线程资源短缺2、碎片化空间3、无法收集浮动垃圾,导致concurrent mode failure,此时会切换成使用 Serial Old收集器来GC老年代
运行时常量池
符号引用:可以理解为是一种占位符直接引用:可以理解为指向类、字段、方法存储在内存中的实际地址的指针
GCRoots
javac等命令工具
java线程2
3、长期存活对象转移到老年代
浮动垃圾:在并发清除阶段,工作线程产生的垃圾对象,本次GC不会收集,下一次GC收集
46
jvm
Serial+CMS
Survior区r相同年龄(例如10)的对象所占内存空间之和大于Survior一半空间,则将年龄大于等10的对象转移到老年代
垃圾收集器组合
Object2
Fieldref
G1
验证
确定类方法版本,实际类+ 实际方法 将方法符号引用转为直接引用
MinorGC前
内存分配策略
jvm内存分配
linux
对象头
java方法栈
Object1
...
垃圾回收算法
类执行
NameAndType
u1 tag;u2 index1;u2 index2;
2、标记所有可达对象
停顿时间:gc时导致暂停工作线程,造成停顿停顿越短,用户体验越好
Eden区
回收线程3
类方法调用执行
Y
对象死亡判断
加载
类加载器之双亲委派机制
栈帧3
1
ParNew过程Parallel Scavenge/Parallel Old过程
重载场景1、参数数量不同:可直接确定2、参数类型不同:根据静态类型确定方法,不关注实际类型3、形参是常量,jvm自动推导形参转化类型,找寻最适合的方法
老年代最大连续空间是否大于历次晋升对象平均大小
回收线程4
1、将类、字段、方法等符号引用解析成对应的直接引用
主内存
1、解决碎片化问题2、不会浪费空间
to
方法说明
jvm内存分区
标记-清除
Bootstrap Classloader
回收算法进行垃圾回收
4、暂停工作线程,根据可回收价值排序进行垃圾回收
java
对象的初始化:1、在new一个对象时,jvm是会执行 实例变量的赋值
新生代
与CMS区别:1、G1可单独使用不需要配合其他年轻代收集器,CMS只适用老年代2、可预测停顿时间3、回收算法不同,不产生空间碎片化
reference
GC区域:堆和方法区
优点:1、解决 碎片化问题2、存活对象少,效率高缺点:3、存活对象多,效率低4、浪费一半空间
网络二进制流
静态分派
ParNew+Serial Old
Object4
不允许失败则触发Full GC
Serial/Serial Old 过程
有效实例
线程共有
Methodref
栈帧2
FullGC0、程序代码System.gc()1、方法区空间不够2、大对象分配给老年代3、Minor GC时,可能引起Full GC
方法体执行
可达性分析法(主流jvm使用)1、通过GCRoots往下寻找能到达的对象都是有效的,除此之外都是可回收的
方法区静态变量引用
有序性
Object6
class字节码
CMS过程
4、动态对象年龄判断
windows jvm
方法区常量引用
macos jvm
关注吞吐量
Utf8
基础算法缺点:1、效率低速度慢2、碎片化
常量池数量
程序计数器
NameAndTyp
u1 tag;u2 length;u1(length) bytes;
Class
u1 tag;u2 class_index;u2 name_type_index;
1、标记GCRoots直接引用对象
source
groovy编译器
Object5
Extension Classloader
关注停顿时间
引用计数法(主流jvm不使用)1、对象头保存引用次数,引用次数为0,则可回收优点:1、简单缺点:1、无法区分强、弱 、虚引用2、无法解决循环引用的问题
4
u1 tag;u1 index;
初始化
1、优先分配在Eden区
垃圾回收算法和垃圾收集器
垃圾收集器
jre
特点:1、多线程2、吞吐量优先3、自适应策略优点:1、在多CPU下,垃圾收集更快缺点:1、在单cpu,浪费线程资源,收集慢场景:1、适合Server模式且后台运算少用户交互
Utf-8
.....
为什么java能跨平台
栈帧局部变量表引用
委托
其他编译器
实例数据
特点:1、serial的老年代版本2、GC时暂停工作线程优点:1、单线程实现简单高效,适合单CPU缺点:1、暂停工作线程导致短暂停顿场景:1、适合Client模式
.class
单一
异常说明
年轻代1、存活对象少,经常回收2、可将老年代作为额外存储
类卸载
CMS
Serial Old
java线程1
分派
本地方法栈
new创建的对象实例都在堆区
1、验证class文件格式2、元数据验证3、字节码验证4、符号引用验证
尝试新生代GC,如果失败则触发老年代GC
Serial
动态分派
Parallel Scavenge+Serial Old
可预测停顿时间原理:避免在全Java堆进行收集1、将内存划分为大小相等Region2、每个Region记录垃圾堆积大小和所需回收时间3、G1维护一个优先列表,根据允许收集时间回收价值最大的Region
线程私有
吞吐量=工作线程时间/(工作线程时间+垃圾收集时间)吞吐量越大,工作分配资源越多,适合后台任务
GC区域和GC时机
实际类已确定,需确定方法
jvm类加载和运行
1、将类成员变量(static修饰)设置初始值(0)
类的初始化:1、jvm会自动生成一个cinit方法,执行类成员变量(static修饰的)赋值 和 static代码片段
栈帧
Long
2、大对象直接分配在老年代
版本
class文件格式
准备
回收线程2
Serial+Serial Old
年轻代
操作数栈
0 条评论
下一页