一、垃圾回收器简介
1、概念:垃圾回收器是用来自动管理虚拟机中内存的,包括自动分配和自动回收的功能,免去了由程序员来释放内存的麻烦。
2、原因:因为由程序员自己释放内存很可能会出现各种问题,如内存泄露或者悬挂引用,从而导致程序终止。
二、常见垃圾回收算法
1、引用计数器法
(1)实现思路:当新的引用指向新的对象时;对象的计数器加1,当引用失效时,对象的计数器减1;当引用计数器的值变为0时,该对象可以被垃圾回收器回收。
(2)优缺点:
I、优点:实现原理非常简单。
II、缺点:不能解决循环引用的孤岛问题。
孤岛问题:假如有三个对象,这三个对象相互引用(此时对象的计数器不为0),但是没有其它对象指向这几个对象,这时这三个对象占着内存不能释放。
2、跟踪法
(1)实现思路:定义一个有向图,把对象看作是图中的每个节点,对象的相互引用是图中节点之间的邻接关系。垃圾回收器从图中的根节点出发遍历图中的节点,
当对象无法到达时,进行垃圾回收。跟踪法解决了孤岛问题,如下图:
三、分代技术(Java HotSpot)
垃圾回收器是基于分代技术进行回收的,即不同代的对象采用不同的回收方法。Java HotSpot虚拟机中包含三代,分别是年轻代、年老代、永久代。
1、年轻代:绝大多数的内存分配回收动作都发生在年轻代。年轻代被划分为三个区域,原始区(Eden)和两个小的存活区(Survivor),两个存活区按功能分为From和To。绝大多数的对象都在原始区分配,超过一个垃圾回收操作仍然存活的对象放到存活区。
2、年老代:主要存储年轻代中经过多个回收周期仍然存活从而升级的对象。
3、永久代:对于一些大的内存分配,可能也直接分配到永久代。
三、回收器分类
1、并行回收器:回收过程和当前应用程序并行执行。
(1)年轻代:把原始(Eden)区的存活对象移到To区,To区装不下直接移到年老代,把From区的移到To区,To区装不下直接移到年老代,From区里面年龄很大的升级到年老代。回收结束之后,原始(Eden)区和From区都为空,此时把From和To的功能互换,From变To,To变From,每一轮回收之前To都是空的。设计的选型为复制。
(2)年老代:年老代的回收分为三个步骤,标记(Mark)、清除(Sweep)、合并(Compact)。标记阶段把所有存活的对象标记出来,清除阶段释放所有死亡的对象,合并阶段把所有活着的对象合并到年老代的前部分,把空闲的片段都留到后面。设计的选型为合并,减少内存的碎片。
2、串行回收器:暂停当前应用先进行垃圾回收。
同并行回收器
另外还有两种方式:并行合并收集器和并发标记清除回收器,这两种回收器的回收机制有些不同。