深入理解Java虚拟机笔记(带目录)
- 格式:docx
- 大小:70.39 KB
- 文档页数:30
目录
1.虚拟机内存结构 (1)
2.对象在内存中的布局 (3)
3.判断对象是否死亡 (4)
4.引用的4中情况 (4)
5.垃圾收集算法 (5)
6.HotSpot虚拟机算法实现 (6)
7.如何在GC发生时让所有线程都要附近的安全点停下 (6)
8.垃圾收集器 (7)
9.GC日志 (9)
10.内存分配 (10)
11.Class类文件的结构 (10)
12.类的生命周期 (13)
13.类加载器 (15)
14.运行时栈帧的结构 (16)
15. 方法调用 (18)
16. 分派 (19)
17.虚方法表 (19)
18.Java内存模型(JMM) (19)
19.内存间的交互 (20)
20.volatile变量 (20)
21.原子性 (21)
22.可见性 (22)
23.有序性 (22)
24.先行发生原则 (22)
25.Java线程调度 (23)
26.线程的状态 (24)
27.线程安全 (25)
28.线程安全的实现方法 (26)
29.锁优化 (27)
30.编译优化技术 (29)
1.虚拟机内存结构
线程私有:虚拟机栈,本地方法栈,程序计数器
线程共享:堆,方法区(包括运行时常量池)
1.1程序计数器
当前程序锁执行的字节码行号指示器,记录下一条需要执行的
指令。
1.2虚拟机栈
生命周期与线程相同,每个方法在执行时都会创建一个栈帧。
方法执行的过程,就是栈帧入栈到出栈的过程。
栈帧用于存放局部变量表,操作数栈,动态链接,方法出口等
信息。
局部变量表存放了编译期可知的基本数据类型和对象引用。1.3 本地方法栈
为虚拟机使用到的Native方法服务。
目前HotSpot虚拟机将本地方法栈和虚拟机栈合二为一。
1.4堆
存放对象实例,所有线程共享。
1.5 方法区(永久代)
存放被虚拟机加载的类信息,常量,静态变量,即时编译器编
译后的代码等。
1.6 运行时常量池
方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
1.7 字面量,符号引用,直接引用
字面量:
通俗解释就是一个变量的值,但是这个值不能超过范围。
int a = 1; 1是a的字面量
213738648则不能是int的字面量,因为超出了int的范围。
符号引用:
以一组符号来描述引用的目标,符号可以是任何形式的
字面量,只要使用时能够无歧义的定位到目标即可。
直接引用:
直接指向目标的指针(类变量,类方法)。
相对偏移量(实例变量,实例方法)。
一个能间接定位到目标的句柄。
2.对象在内存中的布局
对象头(哈希码,GC分代年龄,数据指针,如果是数组还会有数组长度),实例数据,对齐填充
3.判断对象是否死亡
3.1引用计数算法
每个对象添加一个计数器,引用它加1,引用失效减1,为0则死亡,很难解决循环引用问题。
3.2可达性分析算法
从gc root节点开始向下搜索,不可达则已死。
可作为gc root节点的情况:
3.2.1:虚拟机栈本地变量表引用的对象
3.2.2:方法区中类静态属性引用的对象
3.2.3:方法区中常量引用的对象
3.2.4:本地方法栈native方法引用的对象
4.引用的4中情况
强引用,软引用,弱引用,虚引用(幽灵引用)
4.1强引用:new 关键字,强引用还在,则不会被回收
4.2软引用:发生内存溢出钱,会把这些软引用对象列入回收范围
进行第二次回收时会将他们回收
4.3:弱引用:只能存活到下一次垃圾回收之前
4.4:虚引用:与对象的生存时间不发生关系,作用是在这个对象
被回收的时候,收到一个系统通知
5.垃圾收集算法
5.1:标记—清除Mark-Sweep
过程:标记可回收对象,进行清除
缺点:标记和清除效率低,清除后会产生内存碎片
5.2:复制算法
过程:将内存划分为相等的两块,将存活的对象复制到另一块内存,把已经使用的内存清理掉
缺点:使用的内存变为了原来的一半
进化:将一块内存按8:1的比例分为一块Eden区(80%)和两块Survivor区(10%)
每次使用Eden和一块Survivor,回收时,将存活的对象一次性复制到另一块Survivor上,如果另一块Survivor空间不足,则使用分配担保机制存入老年代
5.3:标记—整理Mark—Compact
过程:所有存活的对象向一端移动,然后清除掉边界以外的内存
5.4:分代收集算法
过程:将堆分为新生代和老年代,根据区域特点选用不同的收集算法,如果新生代朝生夕死,则采用复制算法,老年代采用标记清除,或标记整理
6.HotSpot虚拟机算法实现
6.1枚举根节点
回收时如果逐个检查引用(可达性分析)效率低下,通过OopMap 数据结构来得知哪些地方存放着引用
6.2安全点
不会为所有指令都生成OopMap,只会在特定位置生成,这些位置成为安全点。
方法调用,循环跳转,异常跳转等会产生安全点
7.如何在GC发生时让所有线程都要附近的安全点停下
7.1抢先式中断
中断全部线程,如果发现有线程不在安全点上,那么恢复线程,让它跑到安全点上(几乎不使用)