大喵来学习垃圾回收啦~忍不住问一句这是什么垃圾哈哈哈
敲黑板,咳咳,下面干货来了哦
对象判活算法(2种)引用计数法
原理:对对象的引用计数,为0则表示对象不可再使用
缺点:存在对象的互相引用,导致不能再使用的对象引用计数不为0可达性分析算法原理:
通过GC Roots对象作为起点,在引用链上的对象可用,没有任何引用链相连的对象不可用可作为GC Roots的对象:
1.虚拟机栈(栈帧中的本地变量表)中引用的对象
2.方法区的类静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中引用的对象
对象回收算法(4种)标记——清除算法(Mark Sweep)
原理:
标记出所有需要回收的对象,标记完成后统一回收被标记的对象
缺点:
1. 效率问题:标记和清除效率都不高
2. 空间问题:产生大量不连续的内存碎片,没有足够连续内存不得已提前触发下一次收集动作标记—整理算法(Mark-Compact)
原理:
标记出所有需要回收的对象,让存活的对象向一端移动,然后直接清理掉端边界以外的内存复制算法原理:
将内存分为两块,每次只使用其中一块,当这一块内存用完之后,将存活的对象复制到另一块上面,然后将已使用过的内存空间一次清掉优点:没有内存碎片,效率高
缺点:依赖替他内存的分配担保分代收集算法
原理:根据对象的存活周期分为不同代,不同代根据年代特点采用最适当的收集算法
安全点概念:一些特殊位置的点,程序能够停顿下来开始GC的位置
特点:具有让程序长时间执行的特征
如何让GC发生时都跑到最近的安全点上再停顿两种方式:
1. 抢先式中断:先中断所有线程,如果发现有中断的地方不再安全点上,恢复线程,直到跑到安全点上
2. 主动式中断:不直接对线程操作,线程主动用test指令轮询内存页是否可读,不可读时,test指令会产生自现异常信号,异常处理器接收到异常处理信号就会暂停线程等待
安全区域
处理程序不执行的情况
在一段代码片段中,引用关系不会发生改变
区域的任何地方开始GC都是安全的
在线程离开时,检查系统是否完成了根节点枚举
垃圾回收器(7种)Serial收集器
特点:单线程,会暂停其他线程所有工作
优点:简单高效
缺点:STW的不良体验ParNew收集器
特点:多线程
使用:能与CMS收集器配合工作Parallel Scanvenge收集器
目标:达到一个可控制的吞吐量
特点:高效率的利用CPU时间,
使用:主要用于后台运算而不需要太多交互Serial Old收集器
特点:单线程,使用标记整理算法Parallel Old收集器
特点:可以和新生代的Parallel Scanvenge搭配使用,使用标记整理
使用:在强调吞吐量以及对CPU比较敏感的场合CMS目标:获取最短回收停顿时间的收集器
算法:标记——清除
运作过程:初始标记(STW):GC Roots关联的对象
并发标记
重新标记(STW):修正并发标记期间因用户程序运作而导致标记变动那一部分对象的标记 记录
并发清除优点:并发收集,低停顿
缺点:CMS对CPU资源非常敏感:默认回收线程数为(CPU数量+3)/4
无法处理浮动垃圾:在并发清理阶段用户线程还在并行时产生新的垃圾,还需预留足够空间给用户线程使用,通过参数-XX:CMSInitiatingOccupancyFraction调节,如果剩余内存无法满足程序要求,出现失败导致另一次Full GC产生,所以设置参数太高性能反而会降低
空间碎片,连续内存不够时不得不提前触发Full GC,可以在Full GC的处理过程中通过参数-XX:+UseCMSCompactAtFullCollection开启碎片的合并整理过程(无法并发)
内存分配与回收策略对象优先在Eden中分配
大对象直接进入老年代
长期存活的对象将进入老年代
动态对象年龄判断
空间分配担保
G1收集器特点:并行与并发
分代收集
空间整合
可预测的停顿:
(1) 长度为M毫秒的时间片段内,消耗在垃圾回收上的时间不得超过N毫秒
(2) Region划分内存空间以及有优先级的区域回收方式。跟踪各个Region里面垃圾堆积的价值大小,后台维护一个优先列表,根据允许的收集时间,优先回收价值最大的Region过程:初始标记
并发标记
最终标记
筛选回收