JVM虚拟机
2020-09-08 10:08:26 1 举报
AI智能生成
对 JVM 知识的梳理,持续更新!
作者其他创作
大纲/内容
Java内存模型
as-serial
happens-before
作用
子主题
重排序
内存屏障
主内存
工作内存
JVM优化手段
早期(编译期)优化
晚期(运行期)优化
JIT
锁优化
几种锁
自旋锁
锁粗化
锁消除
调优工具
jdk自带
jstat
jps
jmap
VisualVM
...
jhat
jstatk
jinfo
第三方
Arthas
GC Easy
字节码框架
asm
javaassist
javaagent
类的生命周期
加载
将一个二进制流转换成内存中的 Class 对象
class文件、jar
Class文件结构
网络
RocketMQ的消费者可以发 Filter 给 Broker,Broker 会将流解析编译成 Filter
动态代理
jdk
cglib
......
数据库等
类加载器作用于这个阶段
双亲委派模型
如何打破
存在意义
反向依赖
线程上下文
注意点
使用组合,而非继承来复用父加载器的代码
只有被同一个 ClassLoader 实例加载的 Class 对象实例,才会相等
Tomcat 应用隔离
Bootstrap
C++实现
加载路径
/lib
-Xbootclasspath
Extension
Java 实现
sun.misc.Launcher$ExtClassLoader
加载路径
/lib/ext
-Djava.ext.dir
System
Java 实现
sun.misc.Launcher$AppClassLoader
程序默认的加载器
加载路径
-D java.class.path
Custom
用户自定义的加载器
最好实现双亲委派
连接
验证
文件格式验证
魔数
版本号
其他......
元数据验证
字节码验证
符号引用验证
准备
静态变量分配内存并设置初始值
非final为类型的默认值,如引用类型为null,int为0
final为用户设置的值
解析
作用:符号引用替换成直接引用
类或接口解析
字段解析
类方法解析
接口方法解析
初始化
触发初始化场景
四条字节码指令
new
getstatic
putstatic
invokestatic
反射调用类
初始化子类时,会触发父类的初始化
VM启动时,需要指定一个main类,这个类会被初始化
jdk7-MethodHandle什么的?
不会触发的场景
调用类的常量
通过数据定义来引用类【Base[] a = new Base[5]】
通过子类引用父类的静态字段,子类不会初始化
作用
真正执行类中定义的代码
使用
虚拟机字节码执行
方法调用
非方法执行,只是方法的寻址
调用方式
静态分派调用
动态分派调用
解析调用
运行时栈帧结构
栈
线程私有,生命周期同线程
随线程创建而创建
大小、深度固定
使用-Xss100k(stack size)的选项,设置虚拟机栈的大小
栈帧
栈帧包含
局部变量表
存放方法参数和局部变量
操作数栈
通过入栈、出栈完成一次数据的访问
动态连接
静态分派?
动态分派?
方法返回地址
附加信息
取决于虚拟机实现
概念
栈帧是栈的元素,线程中,只有栈顶的栈帧是活动的,称为【当前栈帧】,与之关联的方法称为【当前方法】
随方法的调用而创建,随方法的结束而消亡
GC
哪些对象需要回收(what)
引用计数算法
优点简单,缺点无法解决循环引用
根搜索算法
gc root有哪些?
虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中静态属性引用的对象
方法区常量引用的对象
本地方法栈中 JNI 引用的对象
何时回收对象(when)
按区域划分
Young GC(Minor GC)
对新生代进行回收,对象在 eden 分配,存活的对象在 to 和 from 之间来回移动
触发条件
eden 不足时
Old GC
只清理老年代空间的GC事件,只有CMS的并发收集是这个模式
Full GC
清理整个堆的GC事件,包括新生代、老年代、元空间等
触发条件
System.gc()
元空间不足
Mixed GC
清理整个新生代以及部分老年代的GC,只有G1有这个模式
怎么回收对象(how)
标记-清除算法
优点:速度最快
缺点:有内存碎片
复制算法
缺点:使用一半的内存来进行复制(空间换时间)
适合新生代
优化:将内存分成8:1:1来
标记-整理算法
优点:没有内存碎片
缺点:速度最慢
分代收集算法
新生代
老年代
不同代选用适合自己的算法
谁来回收对象(who)
新生代
Serial(串行GC)收集器
单线程
标记-复制
client 模式默认
ParNew(并行GC)收集器
多线程
标记-复制
配合 CMS
Parallel Scavenge(并行回收GC)收集器
标记-整理
使吞吐量可控(吞吐量 = 用户代码运行时间 / (用户代码运行时间 + GC时间))
老年代
Serial Old(串行GC)收集器
Serial 的老年代版本
标记-整理
1.5之前与Parallel Scavenge配合使用;作为 CMS 的兜底
Parallel Old(并行GC)收集器
多线程
标记-整理
为了替代 Serial Old 与 Parallel Scavenge 配合使用
CMS(并发GC)收集器
标记-清理
目标是最短停顿时间
步骤
初始标记
并发标记
重新标记
并发清理
缺点
对 cpu 资源敏感
浮动垃圾问题
内存碎片问题
G1收集器
safe-point
gc 日志
ygc
full gc
对象组成
对象头
MarkWord
hashcode
age
锁信息
klass
数组长度(如果是数组的话)
实例数据
填充
卸载
目的
将方法区的 Class 卸载掉
卸载条件
所有实例都被回收了
加载这个类的 ClassLoader 被回收了
Class 没有被任何地方引用
内存划分
线程共享
方法区(永久代)
类信息、常量、静态变量、即时编译器编译的代码等
堆
按存活周期区分
新生代
Eden区
Survivor From区
Survivor To区
老年代
线程私有
虚拟机栈
执行 Java 方法
本地方法栈
执行本地方法,HotSpot 把虚拟机栈和本地方法栈合二为一
程序计数器
也叫pc寄存器,记录字节码的地址
堆外内存
引用
四种引用类型
(根据强度排序)
(根据强度排序)
①强引用
(Strong Reference)
(Strong Reference)
②软引用
(Soft Reference)
(Soft Reference)
内存不够时回收,适合缓存
java.lang.ref.SoftReference
③弱引用
(Weak Reference)
(Weak Reference)
发生 GC 就回收
java.lang.ref.WeakReference
WeakHashMap
回收后,被gc的引用会在 referenceQueue 中,每次使用 map 时清理 queue
可能OOM
④虚引用
(Phantom Reference)
(Phantom Reference)
java.lang.ref.PhantomReference
符号引用
字面量
直接引用
可以直接定位到内存的某个位置
0 条评论
下一页