前天我们在写Java技术讲解的时候说过引用现在在Java中分为四种类型,强引用,软引用,弱引用,幻象引用。但是这几者之间有什么关系呢?
在Java中我们都是通过分析来计算对象是否还是存活状态。不是存活状态的对象才能 被清理掉。那么这个分析就是称为可达性分析。这个算法的实现是建立在一系列称为GC Root 的对象作为起点的。根据这些起点往下面搜索。这样就构成了从头开始的多条支路的链式信息树。当最终对象是不可达的状态时就证明该对象已死,那么就可以可回收了。
那么什么样的对象可以称为GC ROOT呢?
在 虚拟机书上是这么定义的
在可达性分析上我们判断训话找那个的算法就是这么一个流程。这个过程中在finalize 对象会有一次自己拯救自己的方式,如果再次不拯救自己进入幻象中,那么就可以让其真正的进行回收。
说完对象的引用之后我们都知道对象在哪种状态会被回收,然而在Java中我们使用的是gc来进行回收的那么,gc是利用什么条件进行回收呢?我们说下gc的算法了解下。gc的算法分为标记-清除算法,复制算法,标记-整理算法,分代收集算法,四种算法
标记-清除算法,分为两个阶段,首先是标记回收对象,然后统一回收对象。这是回收算法中最简单的算法。这个算法有两个不足之处
黑色标记要清除的对象,白色未使用,黑色可回收。从图中可看到就算对象被回收之后造成了很多碎片空间,如果在程序运行的过程中创建了大对象,在空间中没有支持的空间,那么就会出现内存溢出的问题。
复制算法是在上一个算法中提高了效率的解决问题。一般会将内存一份为二,一般内存使用完毕后,将对付复制到空余的地方上,进行清理,但是这个有问题就是每次内存只能使用一般,虽然效率提高但是整体内存缩小了。这是最基础的分割方式,
这样我们在使用的时候就能使用多余的空间进行大对象的创建,不用担心空间不足的情况。
标记-整理算法是在标记-清除算法和复制算法基础上进行扩展的一种,标记过程都是一样的类型。然后在对象处理进行空间清理,不同点在于会将可回收的对象移动到一段,整体进行清理,这样大空间也会有,不会造成碎片化。效率也高,也能整个内存都应用上
分代收集算法根据对象存活的时间不同,将其内存进行块分割,在每个快中进行各个级别的数据清理,该方式更加高效。对症下药。