蔡香满屋
站在牛顿头上吃苹果

1.引用计数法:这是个比较古老而经典的垃圾收集算法,其核心就是在对象被其他所引用时计数器加1,而当引用失效时则减1,不过这种方式有非常严重的问题,就是无法处理循环引用的情况,还有就是每次进行加减操作比较浪费系统性能。

借用网上别人画的图:

 

 

 

由于这种算法存在上述缺陷,所以JVM其实并不使用它,而是使用另一种算法,是根搜索算法。这种算法是现代垃圾回收算法的思想基础。它的做法是:把一些对象设为根对象(也可以说是根结点),当任何一个根结点都不可达某一个对象的时候,这个对象就被认为是可以回收的。基于这种思想,上述引用计数法存在的问题就可以解决了,由于根对象无法到达那三个循环引用的对象,所以这三个对象都是视为可回收的垃圾。

那么什么对象可以作为根对象呢?

    1. Java虚拟机栈中引用的对象;
    2. 方法区中的类静态成员引用的对象(static修饰的);
    3. 方法区中的常量引用的对象(主要是final修饰的);
    4. 本地方法栈中JNI(Java Native Interface)引用的对象。

 

------------------------------------------------------------------------------------------------------------------

2.标记清除法:就是分为标记和清除两个阶段进行处理内存中那个的对象,这种方式也有非常大的弊端,就是空间碎片问题,垃圾回收后的空间不是连续的,不连续的内存空间的工作效率要低于连续的内存空间。

-----------------------------------------------------------------------------------------------------------------

3.复制算法:其核心思想就是将内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中所有的对象,反复去交换俩个内存的角色,完成垃圾收集。

(java中新生代的from和to空间就是使用这个算法)

-----------------------------------------------------------------------------------------------

4.标记压缩法:标记压缩法在标记清除法基础之上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理。

那么为什么新生代和老年代使用不同的算法呢?

答:因为对于新生代来说,它的回收频率很高,但是每次回收耗时都很短,而老年代回收频率较低,但是耗时会相对较长,所以应该尽量减少老年代的GC.

5.分代算法:就是根据对象的特点把内存分成N块,而后根据每个内存的特点使用不同的算法。

6.分区算法:其主要就是将整个内存分为N多个小的独立空间,每个小空间都可以独立使用,这样细粒度的控制一次回收都少个小空间和那些小空间,而不是对整个空间尽心GC,从而提升性能,减少GC的停顿时间。

 判断是否回收的算法
1.引用计数器(jvm未使用)
2,可达性分析(根节点搜索)

posted on 2019-07-13 17:33  蔡香满屋  阅读(145)  评论(0)    收藏  举报