一、GC--Garbage Collection 直译就是垃圾回收。

GC主要是用来回收内存中已经被用完但是未被释放的空间(主要是指堆内存)。通过GC可以一定程度避免内存溢出。

内存垃圾回收并不只是Java虚拟机独创的。很多其他主流语言都有垃圾回收思想。

二、新生代与老年代:

新生代:存放新生代对象的堆,新生代对象指刚创建的对象,或没有经历过几次垃圾回收的对象。

老年代:存放老年代对象的堆,老年代对象指经历过很多次垃圾回收后依然存活的对象。

而我们在这里主要介绍一下GC的几种常用算法。

三、GC常用算法:

1.引用计数法。

算法思想:就是为每个新创建的对象配上一个整型计数器,当这个对象的引用增加一个时,计数器就加一。当这个对象的引用失效一个时,计数器就减一。当计数器为0时,就进行对象的内存回收。

这种算法有一个巨大的缺点:就是无法解决循环引用的问题。所以在Java中不使用这种算法。

2.标记清除法。

算法思想:它将垃圾回收分为两个阶段。

(1)标记阶段:首先从根节点开始。标记从根节点可到达的所有子节点对象。所有未被标记的对象就是清除对象。

(2)清除阶段:清除所有未被标记的对象。

缺点:回收后的空间是不连续的。使用不连续空间分配大对象的内存效率低,所以这种算法对Jvm整体的效率有影响。

3.复制算法。

算法思想:将内存分为两半。每次只是用其中一半。当回收垃圾时。将当前的存活对象复制到未使用的另一半未使用的内存中。然后清除当前内存中的所有对象。交换两块内存的角色。就完成了垃圾回收。

优点:当内存中垃圾较多时,需要复制的对象不多。因此这种情况下该算法十分高效。

缺点:由于将内存一分为二。

注:复制算法适合于新生代。

4.标记压缩(整理)法。

算法思想:相当于标记清除法的增强版。前面也需要从根节点将所有可达对象进行标记。之后将所有被标记的对象压缩到内存的一端。然后清除边界之外的所有内存空间。

优点:效率高,节省空间。不会产生内存碎片(不连续空间)。

5.分代算法。

算法思想:分代算法结合了前面几种算法的优点。它将内存对象的特点将内存分成几块。根据每块内存的特点采用不同的算法进行内存回收,以此提高回收效率。

为什么会用这种设计思想呢。原来新生代对象存活的时间都比较短,很快就会被回收。所以更适合使用复制算法。而老年代往往存活时间较长。所以更适合使用标记压缩(整理)法或标记清除法。

优点:效率高,回收机制更加合理。

6.分区算法。

算法思想:分区算法将整个堆内存分成了连续的小区间。每块小区间都是独立使用和回收的。这样我们就可以控制一次回收多少小区间,一般来说,对空间越大,进行一次GC所需要的时间就越长。这种等待时间有可能导致服务器发生异常情况。所以使用分区算法可以减少等待时间,每次合理的回收若干个小区间,而不是整个堆空间,减少GC的等待周期。