JVM-GC算法
1.什么对象是垃圾?
- 当一个对象没有任何引用指向他的时候他就是一个垃圾
2.GC的作用
- GC的作用实际上很简单就是回收没有用的对象,实际上对象回收后会存在内存碎片化,这样不连续的空间没办法法分配大对象,所以GC也有整理内存碎片化的作用
3.常见GC算法
3.1引用计数算法
- 原理:给每一个对相关保存一个被引用次数的标记值, 被引用一次改值就增加1, 这样在GC回收的时候直接就判断当前值是否为0即可
- 优缺点
- 优点:实现简单
- 缺点:无法解决循环引用问题
- JDK中是否使用?
- 没有被采用
3.2根搜索算法(GC Roots)
- 原理:根搜索算法的原理其实就是以一个集合的对象作为根,开始寻找他们引用了那些对象,能被引用到的对象就不应该被回收。
- 那些对象可以作为GC Roots
- 方法区/堆中的静态常量引用的对象
- 所有synchronized持有的对象
- 当前虚拟机栈中引用的对象
- 如果当前是分区回收,那么其他区的所有对象也可以
- JDK中采用方式
- 注意:
- 标记最终该对象是否为不可达,不是一次标记就能判断的;其中还有个finalize方法可以自救
3.3标记清楚算法
- 原理:首先会对内存中的对象进行标记,如果能到达的对象就标记为可达对象;然后在线性的遍历所有对象去遍历清除
- 缺点:
- 垃圾回收后会产生大量的内存碎片
- 并且在线性遍历清楚的时候整个用户线程也需要停止,所以效率也比较低
3.4复制算法
- 原理:将内存一分为二,每次只使用其中的一半;然后在垃圾回收时直接将使用的内存中的对象拷贝到另外一半内存,然后直接让原本使用的内存全部回收
- 优点:
- 解决了内存碎片化问题
- 实现效率比标记清楚高,以为没有线性遍历的过程
- 缺点:
- 内存浪费比较严重
- 如果存活对象很多回收对象很少,那么这样复制的开销就很大;所以这种算法不适用与垃圾对象很少的区域
3.5标记压缩算法
- 原理:在标记清楚之上进行了内存整理,将所有的对象移动到内存的一端
- 优点:
- 解决了内存浪费问题
- 解决了内存碎片化问题
- 缺点:
- 效率比标记清楚算法更低
3.6 分代算法
- 以上几种算法都有各自的不同应用场景,比如复制算法就比较适合存活对象少的区域,那么在新生代使用复制算法就比较好,而标记整理算法就比较适合用在存活对象多的老年代