垃圾回收算法

1、标记-清除算法

首先标记处出所有需要回收的对象,在标记完成后同一完成所有被标记的对象

缺点:效率问题,标记和清除两个过程的效率都不高

空间问题:标记清除后会产生大量不连续的内存碎片。导致不能找到大片连续的内存,需提前触发垃圾回收。

2、复制算法:

将内存区域划分为大小相等的两块,每次只使用其中一块。当这一块的内存用完了,就将还存活的对象复制到另一块内存上,然后再把使用过的内存空间一次性清理掉。

优点:不用考虑内存碎片

缺点:内存缩小为原来的一半

应用:现在的商业虚拟机都采用这种算法来回收新生代;研究表明,新生代中的对象98%都是朝生夕死

将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survior。当回收时,将Eden空间和Survivor中活着的对象一次性复制到另外一块survior空间上,最后清理掉Eden空间和Survivor空间。当survivor空间不够时,需要依赖其他内存进行担保分配。

3、标记整理算法:

针对老年代;

标记-整理算法

标记存活对象,让所有存活对象都像一端移动,然后直接清理掉端边界以外的内存。

4、分代收集算法

新生代:复制算法

老年代:标记整理算法


对象已死的判断:

1、引用计数算法

给对象添加一个引用计数器,每当有一个地方引用时,计数器就加1,当引用失效时,计数器值就减1;任何时刻,计数器为零的对象是不可能被引用的。

缺点:难以解决对象之间相互循环引用的问题

2、可达性分析算法

通过一系列的称为‘GCRoots’的对象作为起始点,从这些节点开始向下搜素,搜素所走过的路径称为引用链,当一个对象到GC Roots 没有任何引用链相连时,证明此对象不可用。

Java语言中,可作为GC Roots 的对象包括

1、虚拟机栈中引用的对象(正在执行的线程)

2、方法区中类静态属性引用的对象(类变量)

3、方法区中常量引用的对象

4、本地栈中引用的对象

 


 

引用:

强引:Objectobj=new Object();

只要强引用还在,垃圾收集器永远不会回收掉被引用的对象

软引用:描述一些还有用但并非必须的对象对于被软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存异常。

弱引用:也用来描述非必须对象的,被弱引用的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被若引用关联的对象。

虚引用:幽灵引用或者幻影引用,最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,为一个对象设置虚引用的唯一目的就是能在这个对象被回收时收到一个系统通知。



生存还是死亡

即使在可达性分析算法中不可达的对象,也并非非死不可。如果进行可达性分析后,发现对象没有与GC Roots 相连的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize() 方法时,或者finalize()方法已经被虚拟机掉用过,都将视为没有必要。


 

回收方法区:

废弃常量和无用的类




你可能感兴趣的:(垃圾回收算法)