`

java虚拟机学习笔记之垃圾收集(下)

阅读更多

★引用计数收集器

这种方法中,堆中每个对象都有一个引用计数。当一个对象被创建了,并且指向该对象的引用被分配给一个变量,这个对象的引用计数被设置成1。当这个对象的引用赋值给其他任何一个变量的时候,这个变量就增加1。当该对象引用超过生存期或者被设置成一个新的值时,相应的计数变量就会减1。当引用计数为0的时候,这个对象就被当做垃圾收集。在收集的时候,该对象所引用的任何其他对象的计数值也相应的减少1。这种方法中,某个对象被垃圾收集后可能导致后续其他对象的垃圾收集行动。

好处:可以很快的执行,交织在程序的运行之中。对于实时环境很有利。

坏处:无法检测出循环(即两个或者更多的对象相互的引用)。for example:父对象有个对子对象的引用,子对象又反过来引用父对象。另外就是计数的的增加和减少会带来额外的开销。

★跟踪收集器

跟踪收集器追踪从根结点开始的对象引用图。在java虚拟机之垃圾收集(上)中也说到过,跟踪收集,以某种方式来标记。追踪算法被称作“标记并清除”。

1.在标记阶段,垃圾收集器遍历引用树,标记每个遇到的对象

2.在清除阶段,没有被标记的对象被释放,使用的内存被返回到正在执行的程序。在java虚拟机中,清除步骤必须包括对象的终结。

★压缩收集器

该收集器即压缩和拷贝,是标记并清除收集器通常使用的两种策略,也是java虚拟机垃圾收集器中对付堆碎块的策略。这两种方法都是快速的移动对象来减少堆碎块。

压缩收集器把活动的对象越过空闲区滑动到堆的一端,在这个过程中,堆的另一端出现大的连续空闲区。所有被移动的对象的引用也被更新,指向新的位置。被移动对象引用的更新可以间接实现比较简单。不直接引用堆中的对象,实际上指向一个对象句柄表。对象句柄才指向堆中对象的实际位置。对象移动的时候,只有这个句柄需要被更新成为新位置。所有的程序中对对象的引用仍然指向这个具有新值的句柄,句柄的本身没有移动。这种做法也会对象的每次访问带来性能的损失。

★拷贝收集器

拷贝收集器把所有的活动的对象移动到一个新的区域。在拷贝过程中,被紧挨着布置,这样可以消除原本它们在旧区域的空隙。即空闲区。

好处:对象可以在根对象开始的遍历过程中随着发现而拷贝,不再有标记和清除的区分。对象被快速拷贝到新区域,同时转向指针仍然留在原来的位置。转向指针可以让垃圾收集器发现已经被转移对象的引用。然后垃圾收集器可以把这些引用设置为转向指针的值,因此它们现在指向对象的新的位置。

一般的拷贝收集器算法被成为“停止并拷贝”。此方案中,堆被分成两个区域,任何时候都使用一个区域。对象在同一个区域中分配直到被耗尽。此时,程序执行被中止,堆被遍历,遍历时遇到活动的对象被拷贝到另个区域。当停止和拷贝过程结束时,程序恢复执行。依次往复,对于指定大小的堆来说需要两倍大小的内存,由于任何时候都只使用其中的一半,这就是该方法带来的代价。

★按代收集的收集器

针对停止并拷贝收集器的缺点的改进:

1.大多数程序创建的大小大部分对象都具有很短的生命期

2.大多数程序都创建一些具有非常长生命周期的对象

按代收集的收集器通过把对象按照寿命来分组。此方法中,堆被划分成两个或者更多的子堆,每个堆为一“代”对象服务。最年幼的那一代进行最频繁的垃圾收集。最年幼的对象在经历了好几次的收集后仍然存活,那么它就成长为寿命更高的一代,会被转移到另外一个子堆中去。即更高的年龄层去。

按代收集技术可以应用于拷贝算法,也可以应用于标记并清除算法。可以提高垃圾收集算法的性能。

★自适应收集器

自适应收集器主要是根据具体的情况和为了实现更好的目的,采用多种不同的算法来实现垃圾收集。即组合收集器,多种收集器技术的结合使用。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics