1、垃圾收集算法(方法论):
定义:JVM通过GC来回收堆和方法区中的内存。
GC的基本原理:首先会找程序中不再被使用的对象;然后回收这些对象所占用的内存。
算法分类:
(1) 按照基本回收策略分:
<1>引用计数(Reference Counting):
比较古老的回收算法。原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为0的对象。此算法最致命的是无法处理循环引用的问题。
<2> 标记-清除(Mark-Sweep):
Before GC:
After GC:
算法:此算法执行分两阶段:
(1)从引用根节点开始标记所有被引用的对象。
(2)遍历整个堆,把未标记对象进行回收。
缺点:需要暂停整个应用,同时会产生内存碎片。
<3> 复制(Copying):
算法:
(1)此算法把内存空间划分为两个相等的区域,每次只使用其中一个区域。垃圾回收时,从根集合扫描出存活的对象,并将找到的存活对象复制到一块新的完全未使用的空间中。
(2)此算法每次只处理正在使用中对象,因此复杂成本比较小,同时复制过去以后还能进行相应的内存处理,不会出现“碎片”问题。
(3)当要回收的空间中存活对象较少时,比较高效。
缺点:需要两倍内存空间。
<4> 标记-整理(Mark-Compact):
算法:此算法结合了“标记-清除”和“复制”两个算法的优点。也分两个阶段:
(1)从根节点开始标记所有被引用对象。
(2)遍历整个堆,把清除未标记对象并且把存活对象“压缩”到堆的期中一块,按顺序排放。
(3)此算法避免了“标记-清除”的碎片,“复制”算法的空间问题。
缺点:移动对象的成本较高。
(2) 按照分区对待的方式分:
(1)增量收集(Incremental Collecting):
实时垃圾回收算法,即:在应用进行的同时进行垃圾回收。不知道什么原因JDK5.0中的收集器没有使用这种算法的。
(2)分代收集(Generational Collecting):
基于对对象生命周期分析后得出的垃圾回收算法。把对象分为年青代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE1.2开始)都是使用此算法的。
目前常用的算法就是:1,2,3与4的组合。
1、标记-清除(Mark-Sweep):
2、复制(Copying):
3、标记-整理(Mark-Compact):
4、分代收集(Generational Collecting):