JVM
2021-02-25 18:20:17 6 举报
AI智能生成
java虚拟机学习总结
作者其他创作
大纲/内容
JVM
实战
Java 堆溢出
虚拟机栈溢出
本地方法栈溢出
方法区溢出
常量池溢出
本机直接内存溢出
垃圾回收
对象回收的判断
1.引用计数算法
font color=\"#0076b3\
优点:判定效率高
2.可达性分析算法
GC Roots\
作为GC Roots对象
栈帧中本地变量表中引用的对象
方法区类静态属性引用的对象
方法区中常量引用的对象
方法栈JNI引用的对象
强引用 Object obj = new Object
软引用 有用非必须
弱引用 非必须
虚引用 最弱的引用
枚举根节点
安全点
安全区域
方法区回收
垃圾回收效率较低
回收内容
废弃常量
无用类
1.该类所有实例都被回收
2.加载该类的ClassLoader被回收
font color=\"#c41230\
垃圾收集算法
标记清除算法(最基础算法)
1.首先标记出所有需要回收的对象
2.在标记完成后统一回收掉所有被标记的对象
缺点1:标记和清除过程的效率都不高
缺点2:产生大量不连续的内存碎片
复制算法
1.内存按容量划分为大小相等的两块
3.将都是垃圾对象的那块清空内存
缺点1:在对象存活率较高时,复制操作次数多,效率降低
缺点2:內存缩小了一半;需要額外空间做分配担保
标记整理算法
1.标记步骤和标记清除算法相同
分代收集算法
新生代
老年代
标记-清理或者标记-整理
垃圾收集器
Serial(最基本的收集器)
单线程
ParNew收集器
Serial的多线程版本
Parallel Scavenge收集器
新生代收集器
吞吐量较高
多线程
Serial Old收集器
Serial的老年代版本
Parallel Old收集器
Parallel的老年代版本
CMS收集器
回收停顿时间短
标记-清除
1.初始标记 STW
2.并发标记
3.重新标记 STW
4.并发清除
G1收集器
并行并发
分代收集
空间整合
可预测停顿
GC日志
GC日志最前面时间是虚拟机启动以来经过的秒数
【GC 【Full GC 垃圾收集的停顿类型
类加载机制
什么是类的加载机制
类加载的生命周期
加载
1.通过类的全限定名称获取此类的二进制流
2.将这个二进制字节流所代表的静态存储结构转化为方法区的运行时数据结构
3.内存中生成一个java.lang.class对象font color=\"#0076b3\
5.加载和连接是交叉进行的
连接
验证
确保Class文件的字节流中包含的信息符合当前虚拟机要求
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
为类变量分配内存并设置类变量初始值
解析
1.类或接口的解析
2.字段解析
3.类方法解析
4.接口方法解析
初始化
执行构造器 <clinit>
收集类中所有类变量的赋值动作和静态语句块中的合并语句
子类的clinit()执行之前,父类clinit()一定执行完成
不会执行父接口的(),除非要使用父接口中定义的变量
使用
卸载
类加载器
双亲委派模型
启动类加载器(虚拟机中的一部分)
将虚拟机识别的类库加载到内存
其他的类加载器(独立于虚拟机外部)
扩展类加载器
应用程序类加载器
负责加载ClassPath上指定的类库
自定义类加载器
工作过程
虚拟机字节码执行引擎
运行时栈帧结构
局部变量表
操作数栈
动态连接
方法返回地址
分派
静态分派
运行时数据区域
程序计数器PCR
1.较小的内存
2.当前线程执行的字节码行号指示器
3.字节码指示器:通过改变这个计数器的值来选取下一条需要执行的指令
4.线程私有
6.不会内存溢出
java虚拟机栈
1.线程私有
2.生命周期和线程相同
3.每个方法创建栈帧
1.局部变量表
A.存放编译器可知的各种font color=\"#c41230\
C.所需的内存在编译器就确定
2.操作数栈(参数传递池)
算术运算的时候是通过操作数栈来进行的
调用其他方法的时候是通过操作数栈来进行参数传递的
3.动态链接(运行中方法的符号引用的实际指向地址)
保存当前运行方法font color=\"#c41230\
1. Class文件在编译过程中,一切方法调用在Class文件里面存储的都只是符号引用
1. 静态分派--场景:重载--编译过程中根据方法的参数类型确定使用哪个方法的符号引用
2. 动态分派--场景:重写--运行过程中根据对象的实际类型选择使用父类/子类中定义的方法的类方法
4.返回地址
5.异常情况
A:线程请求的栈深度大于虚拟机允许的深度
本地方法栈
2.执行的是native方法
3.异常情况和虚拟机栈相同
Java 堆
1.jvm中内存最大的一块
2.线程共享
3.存放对象实例
4.垃圾回收的主要区域
5.新生代
1.Eden
2.From Survivor
3.To Survivor
6.老年代
7.多个线程私有的分配缓存区TLAB
8.物理上不连续的内存空间
9.异常:内存溢出
(永久代)方法区
1.线程共享
3.运行时常量池(存储编译器生成的字面量和符号引用)
直接内存
NIO中使用这块内存居多(例如: netty零拷贝)
非堆内存受总内存大小限制
对象的创建
1.new 指令创建对象
A:检查这个指令的参数能否在常量池中找到类的符号引用
B:检查这个符号引用是否已经被font color=\"#c41230\
C:没有的话先进行类加载过程
2.分配内存方式
A:指针碰撞
B:空闲列表
D:并发情况下线程不安全
同步
按照线程划分在不同的空间TLAB
3.对象的内存布局
A:对象头
第一部分存储font color=\"#c41230\
第二部分类型指针(通过这个指针确定是哪个类的实例)
数组的话还存储数据的长度
B:实例数据
存储顺序受分配策略的影响:相同宽度的字段总是被分配到一起
父类中的字段信息在子类之前
C:对齐填充
虚拟机要求对象大小是8字节的整数倍
4.对象的访问定位
直接指针访问 详细看对象指针图 优点:速度块
内存分配策略
年轻代
对象主要分配在新生代的Eden区域
font color=\
大对象直接进入老年代
长期存活的对象进入老年代
1.虚拟机给对象添加年龄计数器
2.动态年龄判断
3.空间分配担保
3.老年代会判断font color=\"#c41230\
常用的工具
jps 显示指定系统内所有的虚拟机进程
jstat 监视虚拟机各种运行状态的信息
jmap 生成堆转储快照
jhat 虚拟机堆转储快照分析工具
jstack 生成虚拟机当前时刻的线程快照
类文件结构
class文件是一组以8字节为基础单位的二进制流
由无符号数和表构成
0 条评论
回复 删除
下一页