JVM
2019-09-17 22:32:51 13 举报
AI智能生成
JVM从小白学成大佬。JVM的重要性毋庸置疑,可以毫不夸张的说Java虚拟机是整个Java平台的基石。
作者其他创作
大纲/内容
运行时数据区
堆
1.Java虚拟机所管理的内存中最大的一块
2.所有线程共享,在虚拟机启动时创建
3.所有的对象实例以及数组都在堆上分配
4.Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC堆”(Garbage Collected Heap)
方法区
1.所有线程共享的内存区域
2.存储已被虚拟机加载的类信息、常量、静态常量、即时编译器编译后的代码等数据。
3.这区域的内存回收目标主要是针对常量池的回收和对类型的卸载。
虚拟机栈
栈帧
局部变量表
操作数栈
动态链接
返回地址
本地方法栈
本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务
程序计数器
1.每一条Java虚拟机线程都有自己的程序计数器
2.此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
类加载机制
类的生命周期
加载
连接
验证
文件格式验证
元数据验证
字节码验证
符号引用验证
准备
解析
类或接口的解析
字段解析
类方法解析
接口方法解析
初始化
使用
卸载
双亲委派模型
垃圾回收
如何辨别一个对象的存亡?
引用计数算法
缺点
1.需要额外的空间来存储计数器,以及繁琐的更新操作。
2.无法处理循环引用对象
可达性分析算法
GC Roots对象
1.虚拟机栈(栈帧中的本地变量表)中引用的对象
2.方法区中类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中 JNI(即一般说的 Native 方法)引用的对象
Stop-the-world
1.在Java虚拟机里,传统的垃圾回收算法采用的是一种简单粗暴的方式,那便是Stop-the-world,停止其他非垃圾回收线程的工作,直到完成垃圾回收。这也叫造成垃圾回收所谓的暂停时间(GC pause)
2.Stop-the-world是通过安全点(safepoint)机制来实现的。
垃圾回收算法
标记-清除算法
缺点
1.内存碎片
2.分配效率较低
复制算法
缺点
解决了内存碎片化问题,但堆空间的使用效率极其低下
标记整理算法
缺点
解决了内存碎片的问题,也规避了复制算法只能利用一半内存区域的弊端。看起来很美好,但从上图可以看到,它对内存变动更频繁,需要整理所有存活对象的引用地址,在效率上比复制算法要差很多
分代收集算法
HotSpot的算法实现
枚举根节点
安全点(Safepoint)
安全点的初始目的并不是让其他线程停下,而是找到一个稳定的执行状态。在这个执行状态下,Java虚拟机的堆栈不会发生变化。这么一来,垃圾回收器便能够“安全”地执行可达性分析。
只要不离开这个安全点,Java虚拟机便能够在垃圾回收的同时,继续运行这段本地代码。
程序运行时并非在所有地方都能停顿下来开始GC,只有在到达安全点时才能暂停。
安全点的选定基本上是以程序“是否具有让程序长时间执行的特征”为标准进行选定的。
安全区域(Safe Region)
指在一段代码片段中,引用关系不会发生变化。在这个区域中任意地方开始GC都是安全的。也可以把Safe Region看作是被扩展了的Safepoint。
安全词
GC pause(垃圾回收暂停时间)
知识点
Java虚拟机的堆划分
新生代(1/3)
Eden区(8/10)
Survivor区(2/10)
From区(1/10)
To区(1/10)
老年代(2/3)
GC分类
Minor GC
针对新生代
触发条件
Eden空间满时
Major GC
针对老年代
触发条件
Minor GC 会将对象移到老年代中,如果此时老年代空间不够,那么触发 Major GC
Full GC
清理整个堆空间
一定意义上Full GC 可以说是 Minor GC 和 Major GC 的结合。
触发条件
调用System.gc()
老年代空间不足
空间分配担保失败
卡表
该技术将整个堆划分为一个个大小为512字节的卡,并且维护一个卡表,用来存储每张卡的一个标识位。这个标识位代表对应的卡是否可能存有指向新生代对象的引用。如果可能存在,那么我们就认为这张卡是脏的。
在进行Minor GC的时候,我们便可以不用扫描整个老年代,而是在卡表中寻找脏卡,并将脏卡中的对象加入到Minor GC的GC Roots里。当完成所有脏卡的扫描之后,Java虚拟机便会将所有脏卡的标识位清零。
想要保证每个可能有指向新生代对象引用的卡都被标记为脏卡,那么Java虚拟机需要截获每个引用型实例变量的写操作,并作出对应的写标识位操作。
写屏障
用于减少老年代的全堆空间扫描
TLAB
用于解决多线程竞争堆内存分配问题,核心原理是分配一些连续的内存空间
Java对象创建过程
1.验证类已被解析
2.获取instanceKlass,确保klass已完全初始化
3.若满足快速分配条件,则进入快速分配流程
4.若不满足快速分配条件,或者快速分配失败,则进入慢速分配流程
垃圾收集器
Serial收集器
针对新生代的垃圾回收器,单线程,标记-复制算法
ParNew收集器
针对新生代的垃圾回收器,标记-复制算法,可以看成是Serial的多线程版本
Parallel Scavenge收集器
针对新生代的垃圾回收器,标记-复制算法,和ParNew类似,但更注重吞吐率
不能与CMS一起使用
Serial Old收集器
针对老年代的垃圾回收器,标记-整理算法,单线程
Serial Old是Serial收集器的老年代版本
Parallel Old收集器
针对老年代的垃圾回收器,标记-整理算法,可以看成是Serial Old的多线程版本
Parallel Old是Parallel Scanvenge收集器的老年代版本
CMS收集器
初始标记(CMS initial mark)
并发标记(CMS concurrent mark)
重新标记(CMS remark)
并发清除(CMS concurrent sweep)
G1收集器
初始标记(Initial Marking)
并发标记(Concurrent Marking)
最终标记(Final Marking)
筛选回收(Live Data Counting and Evacuation)
扩展知识点
默认收集器
jdk1.7,1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.9 默认垃圾收集器G1
内存分配与回收策略
对象优先在Eden分配
大对象直接进入老年代
长期存活的对象将进入老年代
动态对象年龄判定
这个地方有坑哦
空间分配担保
头脑风暴
1.Stop-the-world机制这么讨嫌,为什么还会存在呢?
2.JVM运行内存的分类
【面试必考】
3.如何监控和诊断JVM堆内和堆外内存使用
4.如何理解JVM内置的编译或GC日志
5.JVM内存模型(JMM)
【面试必考】
6.什么样的垃圾才被回收
7.什么时候会导致垃圾回收
8.如何利用Unsafe API绕开JVM的控制
9.java中对象创建的过程
10.发现虚拟机频繁full GC时应该怎么办?
11.JVM的分代年龄为什么是15?而不是16,20之类的呢?
0 条评论
下一页