-
1.标记清除算法
-
2.标记复制算法
-
3.标记整理算法
=======================================================================
那么问题来了,什么样的对象在jvm中才能算是垃圾呢?
在java中,有两种判断当前对象是否是可以回收的垃圾:
-
1.引用计数法
-
2.可达性分析法
下面我们先看看什么是引用计数法
为对象添加一个引用计数器存储到一份额外的内存区域中进行记录,当有地方引用这个对象时,引用计数器的值就会+1,当引用失效时,计数器的值就会-1;当计数器的值为0的时候,也就说明当前对象再没有被其他的对象所引用,此时可以计入失效名单标记为待回收对象了;
引用计数器的方式简单明了,不过也伴随着一些问题没办法去解决。当两个对象相互依赖时,也就是循环依赖,此时两个对象即使不再被其他对象所依赖,他们的引用计数器的值也不会成为0,就没有办法被JVM回收了;
可达性分析法是通过以所有的“GC Roots”对象为出发点,如果无法通过GC Roots的引用追踪到的对象,那我们认为这些对象就不会再次被使用了。
如上图,以GC Root作为出发点,被追踪的对象则表示处于存活状态的,而没有被GC Root所追踪的对象,则视为可被回收的对象;
在java中,如下对象可作为GC Root对象:
-
1、虚拟机栈中的本地变量所引用的对象。
-
2、方法区中静态属性引用的对象。
-
3、方法区中常量引用的对象。
-
4、本地方法中(Native方法)引用的对象。
-
5、虚拟机内部的引用对象(类记载器、基本数据对应的Class对象,异常对象)。
-
6、所有被同步锁(Synchronnized)持有的对象。
-
7、描述虚拟机内部情况的对象(如 JMXBean、JVMTI中注册的回调、本地缓存代码)。
-
8、垃圾搜集器所引用的对象。
=======================================================================
我们下面逐步分析一下这三种垃圾回收算法的优缺点以及使用场景
在JVM中,标记复制算法应用于新生代中,新生代对象的特征是大多数对象都是朝生夕死,所以每次复制对象时,只需要复制那些被判定为还活着的对象即可;
通过Eden区和两个S区中间对象的复制从而实现回收。