- 首先说java的垃圾回收机制
- 简述垃圾回收机制
- 在java中程序员不用去显示性的去释放一个对象的内存,而是由虚拟机去自行执行
- 在jvm中,垃圾回收是低优先级的,所以不会在一般的情况下去运行,而实在jvm空闲的时候或者是堆空间满了的时候,才会触发执行
- 可以通过可达性的方式来对没有引用的对象进行一个垃圾处理的行为
- 缺点
- java的垃圾回收机制是自动化的,可控性很差,有时会出现内存溢出的情况
再说说—java是如何确定哪些对象应该进行回收
对象被回收的两个
经典
算法引用计数法
就是用来记录对象被
引用
的次数实现方式
- 给对象添加上一个引用计数器,
- 当该对象被调用时,我们的计数器+1,
- 当该引用失效时,我们的计数器就会-1,当
- 某一个对象的引用计数器为0时,那就说明表示这个对象没有人进行引用,那就意味着它是一个失效的垃圾对象,就会被GC处理进行回收!
缺点
- 这种简单的算法jvm并没有进行使用,原因是她不能解决对象间相互调用引用的问题
- 假设有A和B两个对象之间
互相引用
,也就是说A对象中的一个属性是B,B中的一个属性时A,这种情况下由于他们的相互引用
,从而是垃圾回收机制无法识别
可达性分析算法
- 通过判断对象的引用链是否可达来进行决定对象是否进行回收
- 实现方式
- 从离散数学中的图论引入的,我们会把程序看作一张图
- 通过一系列的名为GC Roots的对象作为起始点
- 从这些节点开始向下搜索,搜索所走过的路径成为
引用链
- 当我们一个对象到我们的GCRoot没有任何的引用链进行连接时(就是从GCRoot到这个对象不可达)
- 则证明此对象时不可用的,就会进行GC处理
再说说- 什么时候进行回收
- 在CPU空闲的时候进行回收
- 在堆空间储存满了之后
- 主动调用System.Gc()后尝试进行回收
如何回收—回收工作原理
- 也就是说的垃圾收集的
算法
- 标记–清除算法(最基础的一种算法)
- 实现步骤
- 一个步骤也就是标记出需要回收的对象
- 标记完成后就进行同一个回收掉那些带有标记的对象
- 缺点
- 空间问题
- 当我们标记后进行清除后,会产生大量不连续的内存碎片
- 再分配
- 当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而造成内存空间浪费
- 复制算法
- 实现步骤
- 我们通过将可用的内存按容量划分为大小相等的两块,每次只去使用其中的一块
- 但我们这一块的内存用完了,就将还存活着的对象复制到另一块的内存上面
- 然后再将已使用过的内存空间一次清理掉,这样使得每次都是对其中的一块进行内存回收GC
- 缺点
- 在对其对象存活率较高时就要执行较多的复制操作时,我们的效率就会降低
- 更关键的是—–浪费了一半的空间
- 标记整理算法
- 实现步骤
- 对其需要回收的对象进行标记
- 然后对其标记的回收对象进行回收
- 与标记清楚算法进行比较
- 标记清楚算法仅对不存活的对象进行处理,剩余存活对象不做任何处理,造成内存碎片
- 而标记整理算法,不仅对不存活的对象进行处理,同时还对剩余的存活对象进行整理,重新整理
- so
- 不会产生内存碎片
- 分代收集算法
- 理解
- 这种算法是一种比较智能的算法,也就是现在jvm使用最多的一种算法
- 算法策略
- 他会在具体的场景自动选择以上三种算法进行垃圾对象回收
- 垃圾回收的各个场景和相应回收策略