JVM垃圾回收算法
1.引用计数法

可达对象:通过根对象索引,最终可以达到的对象
对于对象A被引用一次就+1 失去引用时-1,当对象的计数器为0的时候就会被回收
缺点:
1.无法解决循环引用
2.每一次对象取得引用或者失去引用都会有技术操作影响性能
2.标记清除法

标记阶段:从根对象开始索引 可以被找到的对象就会被标记
清楚阶段:没有被标记的对象就会被回收
缺点:回收后的内存空间不是连续的 堆大对象的存储会造成影响
3.复制算法
如图在A中进行垃圾回收时,把存活对象复制到B中连续的内存区域中后,清空A区域,并把B作为正在使用的内存块。
在Java新生代串行垃圾回收器中,使用了辅助算法的思想,分为eden、from、to三个区。其中from、to可视为大小相等、地位相同,可进行角色互换的区域,也成为survivor空间。用于存放未被回收的对象。如下图所示
在垃圾回收时,eden空间中的存活对象会被复制到未使用的survivor区域中(假设是to),若to中内存空间不够则会直接进入old区,之后会清空正在使用的survivor(假设是from),然后交换from与to的角色
==注意:复制算法一般用于新生代==
4.标记压缩法
复制算法的高效是建立在新生代对象朝生夕灭的特性之上的,但是在老年代的对象中大部分对象都将是存活下来的,所以使用复制算法的成本也会比较高。
标记压缩法是一种老年代的垃圾回收算法。它是标记清楚算法的改良版。与标记清除算法一样,标记压缩法也需要从根节点开始,对所有可达对象做一次标记,但之后并不像标记清楚算法一样仅仅简单的清除未标记对象。而是把所有存活对象压缩到内存的连续区域中,之后清除其他空间。如下图:
==注意:标记压缩法适用于老年代==
5.分代算法
一般来说新生代的对象大部分会被回收,垃圾回收的时间比较短,频率表较高,而老年代的对象很少会被回收,频率较低,但是扫描老年代的对象耗时远大于新生代。所以为了适应新生代的垃圾回收,虚拟机使用了一种叫做卡表(card table)的数据结构。卡表为一个比特位的集合每一个比特位可以用来表示老年代的某一区域中的所有对象是否包含新生代对象的引用。这样在新生代GC的时候,不用花大量时间扫描整个老年代,而实现扫描卡表,若卡表的标记位为1时再扫描对应的老年代。如下图所示:
6.分区算法
分区算法将一整个堆划分成一个个的小块,然后独立回收。优点是可以控制一次回收的数量。