继上一篇的Java虚拟机部分的内容接着写,上一篇讲的是有关类加载的,这一篇我写写垃圾回收相关算法,理念吧,

上一篇的引子《Java类加载》想要看类加载的内容可以看一看。

一、对象存活算法

首先我们要回收一个对象,首先得知道这个对象是不是存活。如果对象存活则不能够继续回收,如果是已经死亡的对象,则应该立即回收。

首先我们要想确定一个类是不是存活,一般来说有两个方法比较成熟。

1,引用计数法

  当有一个引用指向一个对象时,这个对象的引用个数加1.当一个对象的引用个数是1的时候,就可以判断这个对象将不再使用,或者说是一个死亡对象。

但是这个算法存在一个问题,可能会出现相互引用的问题,从而让这一类得对象没有办法回收,就像下面这样。

在这种情况下,虽然a与b都没有指向了,然是由于a里面还引用了b,b里面页引用了a.所以致使他们得引用数始终是1.最终没有办法回收对象。

2,根搜索算法

根搜索算法实质上是通过设置一系列的"GC ROOTS"对象,通过这些对象作为起始点,开始向下搜索。在向下搜索的过程中,如果对象在这个搜索的路劲上出现了,那么就认为这个对象是存活的对象。加入现在有一个对象不再任意一个的“GC ROOTS”对象的搜索路径上,那么就认为这个对象是一个已经死亡的对象。

我们通过下面的图,来看一下。

上图中国,教深的蓝色就是GC Roots对象,我们通过GC roots对象向下搜索,可以知道,Obj 1,2,3都在GCroots对象的搜索路径上,而Obj5,6不再搜索路劲上,随机即便Obj 5,6的引用个数都是1,但这两个对象依旧是死亡的对象,后面我们就可以清除他们。

二、垃圾回收算法

现在比较流行的垃圾回收算法呢一般有3种算法,每种算法各自有各自的优点和不足。这里我简单介绍一下。

1.标记清除算法

标记清除算法的主要思想是,我们将首先发现有那些对象是已经死亡的,然后 给这些死亡的对象加一个标记,以供后期区清理释放内存。

所以它可以分为两个阶段来处理,第一个阶段是“标记”阶段,这里的标记并不是说只标记一次,而是要经过两次标记。

两次标记:

我们通过根搜索算法,发现某个对象不再搜索路径上的时候,并不是说这个对象会被立马回收,而是有可能被回收。要想正真确定一个对象是否应该被回收需要看第二次标记的结果,当这个对象在经历第二次标记的时候首先判断这个对象的finalize方法是不是已经由JVM调用过了,或者有没有重载如果没有重载那个这个对象将会被立即标记为必须回收的休想,也就是它通过了第二次标记,如果这个对象被重载了,且finalize函数执行的比较慢,或者这里出现了异常,又或者出现了死循环还可能出现让搜索路径上的任意一个对象有了对这个对象的引用那么这个对象将会被立即移除已经标记完成的集合种,并且此次垃圾回收不会被回收。

标记清除算法,事项那些经过标记后的对象,全部回收掉。这种算法呢有着很大的问题,首先它的标记过程和清除过程都是非常消耗时间的。并且呢他会形成非常多的内存空间碎片。如下图所示。

这里我就不画图了,直接借用别人画好的一张图,我们可以看到在回收了死亡对象之后出现了许多的内存碎片,实际上这是非常不利与程序运行的。如果在程序运行的过程中,要分配一个比较大的对象的话,很有可能会提前触发一次GC.

2.复制算法(复制压缩算法)

复制算法比较简单,但是他又一个前提就是将对象分为完整的两块,每次GC首先将存活的对象移动到一侧,然后完全清除掉另外一侧的对象。

我们可以看一下下面的示意图:

我们呢首先将整个内存分为两个区域,每次将存活的对象复制到另外一个区域。完后完全清除另外一个区域。这种算法完全的解决了内存碎片的问题,但是又造成了一种新的问题,就是对于内存的利用率不高,同一时刻只有一般的内存能够被利用。

3.标记整理算法

标记整理算法可以说是解决了上面的两种算法的问题,既解决了内存碎片,也解决了内存利用率不高的问题。

它是每次GC将存活的对象移动到内存的一侧,然后以存活对象划定边界,清除边界以外的所有对象。

具体看下面的效果图:

我们将所有的存活对象移动到一边之后,直接清楚到边界外的所有区域。这个算法完美的解决了内存碎片的问题,是一种用的比较广泛的回收算法。

三、垃圾回收理念

除了以上的回收算法呢,还有一种垃圾回收理念。就是通过大量的分析呢,大量的对象创建时间不久就会死亡(这是指的是那些局部变量,既朝生幕死的对象),而当部分对象经过好多次的GC都没有被回收的时候,基本上这些对象一般比较稳定了,死亡的比例将会比较少。

我们最长使用的HotSpot虚拟机就是采用的分代回收的一种理念。它将内存分为“永久代”,"新生代","老年代".在不同的区域存放着不同的对象,新生代的对象很容易被回收,采用这种理念,大大的降低了回收的难度和减短了回收的时间。减少了标记和清除的时间,提高吞吐量,减少“STOP THE WORLD”的时间。

猜你喜欢

转载自www.cnblogs.com/leiroliu/p/11863704.html