Skip to content

Latest commit

 

History

History
28 lines (28 loc) · 2.39 KB

2021-3-25-2.md

File metadata and controls

28 lines (28 loc) · 2.39 KB

Java 中垃圾回收机制中如何判断对象需要回收?常见的 GC 回收算法有哪些?

Java 中垃圾回收机制中如何判断对象需要回收?

引用计数法:可以通过引用计数法(reference counting),为每个对象添加一个引用计数器,用来统计指向该对象的引用个数。 一旦某个对象的引用计数器为0,则说明该对象已经死亡,便可以被回收了。 无法解决循环引用的问题,主流垃圾回收器不用。
可达性分析:GC Roots可以理解为由堆外指向堆内的引用,一般而言,GC Roots包括以下几种:
1.Java方法栈中的局部变量
2.已加载类的静态变量
3.JNI handles
4.已启动且未停止的Java线程
从GC Roots出发,把可以到达的对象加入存活对象合集之中。

常见的 GC 回收算法有哪些?

标记清除算法

分为标记和清除两个阶段。先从根集合进行扫描,对存活对象标记,标记完毕后,再扫描整个空间未被标记的对象进行回收。
缺点:
1.标记和清除的两个过程效率都不高
2.清除之后会产生大量不连续的内存碎片,内存碎片太多会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存 而不得不再触发一次垃圾回收动作

复制算法

将可用内存按容量划分为大小相等的两块,每次只用其中一块。当这一块内存用完了,就将活着的对象复制到另外一块上面,再把之前 使用过的内存空间一次清理掉,适用于对象存活率低的场景,比如新生代。这样使得每次都是对整个半区进行内存回收,实现简单, 运行高效。每次都是对整个半区进行内存回收,内存分配时也不用考虑内存碎片的情况,实现简单,运行高效。
缺点:对内存会有一定的浪费。

标记整理算法

标记整理过程类似于标记清除算法,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉 端边界意外的内容,适用于对象存活率较高的老年代场景。

分代收集算法

根据对象的生命周期,将对象放在不同的区域,不同的区域采取不同的回收策略。新生代对象存活率低,就用复制算法,老年代 存活率高,就用标记清除算法或者标记整理算法。