GC四种垃圾回收算法

JVM中的垃圾
定义:JVM内存中随着方法执行创建的对象,在方法执行完成后不再引用,也没有被清除掉,依旧保存在内存中,这种不会被再次引用的对象就是JVM中的垃圾

JVM内存中大部分对象都是随着方法的执行而创建,方法执行完毕后这些对象就不会被再次引用. 但是这些对象不会被清除掉,就会导致JVM内存中的对象越来越多
此时,需要一种机制将这些不会被再次引用用的对象清除掉,这些不会被再次引用的对象就是垃圾

JVM中的垃圾定义
JVM中通过一种机制清除那些不会再次使用的对象,在清除垃圾对象之前,需要判断哪些对象是可回收垃圾,需要进行垃圾回收清除

 

引用计数(Reference Counting)算法
引用计数算法在每个对象都维护着一个内存字段来统计它被多少”部分”使用—引用计数器,每当有一个新的引用指向该对象时,引用计数器就+1 ,每当指向该引用对象失效时该计数器就-1 ,当引用数量为0的时候,则说明对象没有被任何引用指向,可以认定是”垃圾”对象.

标记一清除( Mark-Sweep )算法:
首先标记出存活的对象,那些没有被标记的就可以 被收集了。此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象, 第二阶段遍历整个堆,把未标记的对象清除。

他的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作, 导致频繁的垃圾回收

复制( Copying )算法:
将内存分成两部分,收集的时候,存活的对象从一部分被移动 到另一个部分,如此往复。此算法把内存空间划分为两个相等的区域,每次只使用其中 一个区域。垃圾回收时,遍历当前使用区域, 把正在使用中的对象复制到另外一个区域 中。然后清理使用过得内存空间,此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还 能进行相应的内存整理,不会出现“碎片”问题,只要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。当然,此算法的缺点也是很明显的, 就是需要两倍的内存空间(或者将内存缩小为了原来的一半)。

标记-整理( Mark-Compact )算法:
此算法结合了“标记,清除”和“复制”两个算法 的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整 个堆,清除未标记对象并且把存活对象“压缩”到堆的其中一块连续的区域,按顺序排放。此算法 避免了“标记-清除”的碎片问题,同时也避免了“复制”算法的空间问题。

 

分代收集( Generational Collecting )算法:
这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成。而老年代中因为对象存活率高、没有额外空间对他进行分配担保,就必须使用“标记-清理”或者“标记-整理”算法来进行回收。

posted @   暖灯夜话  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示