标签:收集 html 循环引用 开始 原来 交换 执行 变化 完成
JVM GC是:JVM的垃圾回收算法,现在的JVM基本采用分代收集,Young区收集平凡,Old区收集较少,Perm(永久代)基本不回收;JVM进行GC时大部分是对新生代的回收,少量的全局回收。
GC按照作用的区域分为:
Minor GC:作用于新生代
Major GC(Full GC):作用于老年代,偶尔也会回收老年代和永久代。
1、引用计数法
引用计数算法很简单,它实际上是通过在对象头中分配一个空间来保存该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加一,如果删除对该对象的引用,那么它的引用计数就减一,当该对象的引用计数为0时,那么该对象就会被标记为垃圾对象。
第10行 str引用了“ABC” 则“ABC”的计算器等于1。第11行str释放了该引用,所以“ABC”的计数器就减一。
优点:实现简单,判定高效,可以很好解决大部分场景的问题。
缺点:
2、可达性分析法(根搜索算法)
可达性分析法:通过一系列"GC Roots"对象作为起始点,开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,认为该对象不可达,则证明该对象是不可用的;
优点:
缺点:
哪些对象可以作为GC ROOT对象(GCRoot 可以是一个也可以是多个):
1、标记-复制:它将可用内存容量划分为大小相等的两块,每次只使用其中的一块。当这一块用完之后,就将还存活的对象复制到另外一块上面,然后在把已使用过的内存空间一次理掉。
JVM实现原理:Survivor区,一块叫From,一块叫To,对象存在Eden和From块。当进行GC时,Eden存活的对象全移到To块,而From中,存活的对象按年龄值确定去向,当达到一定值(年龄阈值,通过-XX:MaxTenuringThreshold可设置,默认=15)的对象会移到年老代中,没有达到值的复制到To区,然后直接清空Eden和From。之后,From和To交换角色,新的From即为原来的To块,新的To块即为原来的From块,且新的Form块中对象年龄加1.
优点:内存分配时也不用考虑内存碎片等问题;实现简单,运行高效;可以利用指针碰撞(bump-the-pointer)实现快速内存分配
缺点:
应用场景:
2、标记-清除:首先标记出需要回收的对象,标记完成之后统一清除对象。
标记:从根集合开始扫描,标记存货的对象
清除:扫描整个堆内存空间,回收未被标记的对象,使用free-list记录可以使用的区域
优点:基于最基础的可达性分析算法,它是最基础的收集算法;而后续的收集算法都是基于这种思路并对其不足进行改进得到的;
缺点:
应用场景:针对老年代
3、标记-整理
标记-整理:标记操作和“标记-清理”算法一致,后续操作不只是直接清理对象,而是在清理无用对象前,先将存活的对象都向一端移动,并更新引用其对象的指针,然后直接清理掉端边界以外的内存。
标记:和“标记-清理”算法一致
整理:扫描整个堆内存空间,将存活的对象都向一端移动,并更新引用其对象的指针,然后直接清理掉边界以外的内存。整理的目的就是整合零散分布的空间碎片为一个连续的空间。
优点:
缺点:主要是效率问题:除像标记-清除算法的标记过程外,还多了需要整理的过程,效率更低;
应用场景:回收老年代;
4、标记-清楚-整理(Mark-Sweep-Compact)
该算法是标记清除和标记整理的结合,标记-清除会产生碎片,标记-整理每次都进行整理效率不高;标记-清楚-整理 是如果老年代内存中没有一块连续续的空间可以存放将要进入对象,就进行整理;如果内存中的空间可以存放将要进入的对象,就进行标记-清除,这样就节省了整理的步骤可以提高效率。总结一句话:不是所有的时候都需要整理的,因为整理也付出代价。主要应用于老年代
总结: 没有最好的算法,只有最合适的引用场景
下一节:GC算法的实现
标签:收集 html 循环引用 开始 原来 交换 执行 变化 完成
原文地址:https://www.cnblogs.com/jalja365/p/12181912.html