本文记录jvm主要知识点 有许多内容没有记录,不涉及太深的知识,只是简单总结。
常见知识点:类加载、内存模型、垃圾回收算法、垃圾回收器
1、类加载
类的生命周期主要包含一下部分
类加载的过程分为 加载、验证、准备、解析、初始化 五个步骤。
加载:将class字节码文件加载到内存中,生成Class对象
验证:确保加载的类信息符合JVM规范
准备:为static变量分配内存并设置初始值
解析:虚拟机常量池内的符号引用替换为直接引用(地址引用)的过程
初始化:执行类构造器()方法,为变量赋初始值
2、内存模型
jvm内存模型主要包含一下几个部分:堆、本地方法栈、虚拟机栈、程序计数器、方法区(元空间)
其中线程共享的有 堆、方法区;线程私有的是 本地方法栈、虚拟机栈、程序计数器
- 程序计数器:读取指令,实现代码的流程控制,无OutOfMemoryError 现象
- java虚拟机栈:线程私有,生命周期和线程一致。随方法的调用和返回而入栈出栈,每次方法调用都会产生一个栈帧 用于存储 [局部变量表、操作数栈、动态链接、方法出口] 等信息。会有StackOverflowError和OutOfMemoryError
- 本地方法栈:和虚拟机栈相似,区别是 虚拟机栈执⾏ Java ⽅法服务,⽽本地⽅法栈则为虚拟机使⽤到的 Native ⽅法服务。
- 堆:内存空间最大的区域,也是垃圾回收主要的地方。存放对象实例,⼏乎所有的对象实例以及数组都在这⾥分配内存。有OutOfMemoryError
- 方法区:存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
- OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。
下面用一张图来总结java内存模型的内容
3、垃圾回收算法
常见的垃圾回收算法:复制算法、标记-清除算法、标记-整理算法、分代回收算法。
- 复制算法:将内存空间分为两快,标记存活的对象复制到另一块内存上,原有内存的对象全部回收。实现简单,运行高效; 空间利用率低
- 标记-清除算法:分为标记阶段和清除阶段;先标记 在清除。缺点:容易产生内存碎片、两次扫描内存。
- 标记-整理算法:分为标记阶段和整理阶段;先标记 在整理。标记清除的优化,避免了内存碎片,效率高。
- 分代算法:将空间分为新生代、老年代。新生代又分为Eden、s0 s1区,8:1:1 。Yong区采用复制算法; Old区采用标记清除或标记整理;
详细垃圾回收算法请查看https://zhuanlan.zhihu.com/p/54851319
4、垃圾回收器
常见的垃圾回收器有 串行垃圾收集器、并行垃圾收集器、CMS、G1
垃圾回收器
大体上分为串行、吞吐量优先、响应时间优先
1、串行垃圾回收器 Serial+SerialOld(复制-新生代 、 标记清除-老年代) STW
- ParNew收集器: Serial收集器的多线程版本,也需要stop the world,复制算法。
2、吞吐量优先 Parallel Scavenge+ParallelOld (复制-新生代 、 标记整理-老年代) 多线程的
.
3、响应时间优先 CMS垃圾收集器 + Serial和arNew (老年代-标记清除 、 新生代-复制)
CMS垃圾收集器 ,标记清除算法,他是一个多线程的,追求最短垃圾回收停顿时间。
主要分为四个步骤
- 初始标记 用户线程阻塞,标记gcroot不可达对象。
- 并发标记 不需要暂停,进行gcroot跟进过程。
- 重新标记用户线程暂停,重新标记不可达对象
- 并发清除 多线程并发清除
G1收集器,标记整理算法
初始标记,并发标记,最终标记,筛选标记,没有内存碎片
精确控制时间,不牺牲吞吐率的情况下,实现低停顿垃圾回收区域划分,垃圾回收
ps:图片来源于网络
本文只是内容的记录,不够详细的地方请参考https://blog.youkuaiyun.com/qq_41701956/article/details/81664921