目录
1.如何判断一个对象是垃圾(两种算法)
1.引用计数法
2. 可达性分析算法
2.垃圾回收算法
2.1标记清除法(老年代回收算法)
2.2 复制算法(新生代回收算法)
2.3 标记整理算法(老年代gc)
2.4 分代回收算法(jvm中采取的算法)
3.垃圾回收器
java语言中,不用自己分配内存,也不用自己回收垃圾(因为jvm中实现了垃圾回收机制)
pubilc class A{ //成员变量 private Person x = new Person(); //静态变量 public static Person y = new Person(); //局部变量 pubilc static void xxx(){ Person z = new Person() } }1.垃圾回收是指在堆中的对象(=右边的对象)
2.=左边的变量与内存区域销毁有关
x成员变量:创建A对象,才创建x,随着A对象的销毁,x也销毁
y静态变量,类加载的时候,才创建y,类销毁的时候,y也随之销毁
x局部变量:执行到这行代码才创建,出了作用范围,z销毁
1.如何判断一个对象是垃圾(两种算法)
1.引用计数法
如果一个对象被引用一次,计数器+1,如果计数器=0,就表示是垃圾,可回收
缺陷:无法解决循环问题
2. 可达性分析算法
GC Roots:垃圾回收要检查的根节点
引用链:某个对象到GC Roots的路劲
如果一个对象到GC Roots是不可达的就是垃圾
2.垃圾回收算法
2.1标记清除法(老年代回收算法)
分为两个步骤
1.标记:标记对象
2.清除:回收垃圾对象
类似于在一个文件夹中,要删除文件,先一个一个选中,然后删除
缺陷:(1)两个阶段效率都不高
(2)内存碎片:清除后产生大量的内存碎片,剩余的空间足够存放某个大对象,但连续空间不够,所以无法存放
2.2 复制算法(新生代回收算法)
将某个取悦划分为两块大小想听的空间,每次只使用其中一半,回收就是把存活的对象复制到另一半空间,清楚之前使用的空间
将某个取悦划分为两块大小想听的空间,每次只使用其中一半,回收就是把存活的对象复制到另一半空间,清楚之前使用的空间
类似于本地文件夹,找到非垃圾文件,复制到另一个文件夹,删除之前的文件夹
使用场景:大多数具有朝生夕死的对象
缺点:空间利用率不高,只有50%;
jvm中的复制算法
将空间区域划分为一块E区和2块S区 ,其中每次使用E区和一块S区,jvm的默认空间利用率为90%
创建一个对象,放在新生代,如果放不下就会触发新生代gc
一个对象在S区存活超过15,就会进入老年代
2.3 标记整理算法(老年代gc)
过程:(1)标记
(2)整理,将存活的对象往一端移动,然后清理到端外的空间
过程:(1)标记
(2)整理,将存活的对象往一端移动,然后清理到端外的空间
2.4 分代回收算法(jvm中采取的算法)
没有具体的实现,只是把不同的区域,采取不同的垃圾回收策略
具体的:内存(堆)划分为新生代和老年代,新生代采取复制算法,老年代采取标记清除和标记整理算法
3.垃圾回收器
垃圾回收线程,可以并行执行,但是用户线程可以同时执行,也可能会暂停(STW(stop the world))
吞吐量:CPU执行用户代码的时间/CPU执行整个进程的时间(用户代码执行的时间+垃圾回收线程执行时间)
用户体验时间:stw单次停顿时间越长,用户体验感就越差
stw单次停顿时间短,整个stw时间长一点,用户体感更好
1.Serial收集器 :新生代收集器(复制算法),单线程的方案
2.ParNew收集器:新生代收集器(复制算法),多线程,搭配CMS(老年代收集器)的方案
3.Parallel Scanvenge收集器:新生代收集器(复制算法),吞吐量优先,搭配Parallel old
4.Serial Old收集器:老年代收集器(标记整理算法),单线程
5.Parallel Old收集器:老年代收集器,吞吐量优先
6.CMS收集器:老年代收集器,标记清除算法,用户体验优先
整体看是线程并发,垃圾回收器线程和用户线程同时执行,有局部的stw,一般搭配新生代ParNew收集器,并发收集,低停顿
分为四个步骤:
1.初识标记:标记GC Roots能直接关联的对象,需要STW
2.并发标记:进行GC Roots引用链追踪的过程
3.重新标记:修复第二个阶段用户线程同时执行时,产生标记变动的记录,需要STW
4.并发清除:并发清除垃圾
缺陷:(1)CPU资源比较敏感:用户体验率高就意味着单次停顿时间短,整个停顿时间长,CPU利用率下降
(2)浮动垃圾的问题(第四个阶段用户线程并发执行时产生的垃圾,在此次GC无法回收,称为浮动垃圾)
(3)内存碎片问题:标记清除算法就会导致该问题,可能会提前触发gc
7.G1收集器(全堆的收集器)
使用G1,堆取得内存划分就不是一个新生代
而是将内存空间划分为多个大小相同的region区,动态分配为E区,S区,T区(老年代)
1.老年代收集器
2.全堆收集器,整体看是标记清除算法,局部看是复制算法
3.用户体验优先
4.步骤
新生代回收:回收多个e区+多个S区,复制对象到存活的空的region区
老年代回收:分为四个阶段
(1)初识标记:和层面上类似(标记GC Roots的关联对象,stw)不同的是,它可以和新生代gc同时发生
(2)并发标记:和cms类似,
(3)最终标记:和cms类似
(4)筛选回收:筛选出存活率低的region回收