了解垃圾回收算法先了解一些东西
什么是对象死亡?
当一个对象当不在被调用时,便判定为死亡
如何判定对象死亡?
两种方法:
引用计数器
给对象添加一个计数器,当这个对象被调用时该计数器+1,当引用失效时该计数器-1。
当计数器为0时表示该对象不可能再被使用。此时该对象便定义为死亡
根搜索算法
通过一个名为GC Roots的对象作为起始点,然后从这个节点开始向下搜索,可以达到的节点进行了标记。当没有标记的对象则为已经死亡的对象。
引用?
为什么会说引用,因为引用和引用计数法和根搜索法有关
引用可以分为四种
强引用
强引用是指程序在代码中普遍存在类似 Object obj=new Object() 这种便是强引用,只要强引用还在,垃圾回收机器永远不会回收被引用的对象。
软引用
描述一些还有用,但并非必需的对象。在内存将要溢出前会将这些对象进行回收。
弱引用
也是来描述非必需的对象,这些对象无论内存是否足够,在下一次垃圾回收器之前进行回收
虚引用
它时最弱的引用,唯一的作用就是在垃圾回收时得到一个系统通知。
常用垃圾回收算法一共有四种
1.标记清除法
标记清除法是当内存不够用的时候,暂停当前程序,运行使用该算法
标记清除法,正如同它名字一样。分为两个步骤分为标记和清除
标记:标记所有根部可到达的对象,给可达到的对象所有打上一个标记
清除:遍历所有元素,将未标记所有对象的内存回收
缺点:
遍历两遍所以效率不高
当它回收后,内存都是一段一段不连续的地址,当需要更大内存时,却需要其它的算法来重新清除内存。
2.复制算法
复制算法就是将所有内存对半分为两部分ab都为内存的一半。每次使用只用内存的一半,也就是ab只使用其中一个。
当需要内存时,都存入a部分,当内存a需要清理时,,将a所有的活动的对象存入b中,把所有不需要的内存回收。
此时b就是现在所存的内存,而a就是空闲内存。
其实就是相当于两个相同长度的数组ab。a和b的和为总内存。
当需要内存是,将存入a,最后a中有些空间已经被取出,但是此时a数组已经遍历到了最后前边内存虽然为空闲但是也无法使用,所以将a中所存的数据都按顺序存入b中,此时就将之前不用内存又可以使用了
优点:
这个算法明显解决了标记清理法的缺点
缺点:
但是又产生了一个的缺点就是将所有内存减少为原来的一半
3.标记整理法
标记整理就是在标记清除法上改进的。分为标记和整理
1.首先将所有需要的对象进行标记
2.其次将已经标记的对象向一端,而将未标记的对象移除内存。
优点:
这样就解决了标记清除法的弊端,这样所有的需要的对象已经存储到 一端连续的内存,这样就不存在一个个片段的内存。都是一段连续的内存。
缺点:
效率更加的低,对需要清除的内存和活动内存都需要标记。
4.分代收集
分代收集算法,相当于将前3个算法结合
了解这个算法首先得了解三个名词:新生代、永久代、老生代。
新生代:就是活动时间不长的对象。它所占用内存时间不长就要回收的。
老生代:相对新生代,它存活时间比较长。它所占用内此时间比较长但是还是要回收的。
永久代:它几乎永久占用内存。
新生代和老生代在jvm堆中存储。
永久代存储在方法区。
新生代会占用内存的20%,但是对于新生代应用的是复制算法,相当于只占了10%的内存。因为新生代内存本来存活时间短所以清理的也快。
老生代使占用了内存80%,老生代是有新生代中移过来的,比如有些对象经历了10次内存清理,则此时把新生代的对象移到老生代中。因为老生代存活时间比较长所以占用内存也比较多,使用的算法也是标记清除法。
永生代:使用算法未标记清理法。
上边内容为我在网上找资料学习加深自己的记忆
我学习文章的链接:https://blog.csdn.net/mccand1234/article/details/52078645