闲聊GC垃圾回收机制

这里只是浅谈一下我自己对GC的理解,如果有什么不对的地方欢迎大家指正交流

GC的定义

GC就是常说的jvm的垃圾回收机制,粗略的理解就是jvm虚拟机可根据复杂的算法策略判断程序中的一段资源是否为可回收状态,而进行自动回收,释放内存资源的一个过程。

以前JVM判断对象存活还是死亡是使用引用计数算法,但现在是使用类似于树形结构的可达性分析算法,也就是GC roots算法。引用计数算法我知道的好像是redis还在用其进行内存回收。

垃圾回收是发生在内存堆区中的,在这里我就不画了,先来个网上找的jvm的体系结构图

JVM体系结构图

图片出处:https://www.cnblogs.com/hexinwei1/p/9406239.html

上方的运行时数据区就是常说的jvm运行内存

 

GC Roots算法

我的理解就是按树状结构以称为GC Roots的一些对象作为起始节点, 开始向下搜索, 搜索过程中所走过的节点引用路径就是引用链,一个堆中一个对象到 GC Roots 没有任何引用链可以连接时(就是没有任何指针可以指向当前对象内存地址),则证明此对象当前状态是不可用的,也就是这个对象死了。

 

回收策略

有四种算法 (标记、复制、标记整理、分代收集),分代收集是对前三种的整合,当前jvm虚拟机回收策略是使用分代收集算法。

 

标记算法就是将内存中GC root判断为死亡作为的对象作为未标记资源直接清除

标记算法的不足就是效率低,对整个内存堆区的标记和清除都是依次进行的,所以效率都不高。并且还有空间问题,这种方法清除资源时会产生大量不连续的内存碎片,内存中不连续的空间碎片太多可能会导致在程序运行过程中分配较大对象时,无法找到足够的连续内存,使得程序要提前发出另一次垃圾收集指令。

 

复制算法就是将内存空间分成大小相同的两块,每次只使用一块,一个内存块满了,执行垃圾回收时将存活对象复制到空白的那一块,然后清除正在使用的内存块,清除后将存活对象再放回来。

复制算法的不足是不适用于存活对象较多的情景,存活对象较多时效率较低,因为正在使用的内存一直是原来的一半了。

 

标记整理算法是对标记算法的优化,就是在将要清理垃圾资源时,将存活对象压缩到内存的一角,然后将这一角外的所有内存空间直接清理

 

三种算法比较

时间复杂度:复制>标记整理>标记

内存利用率:标记整理 > 标记清除 > 复制

内存整齐度:复制 = 标记整理 > 标记清除

老年代存放的对象存活的时间较长,而且垃圾回收的频率不如新生代的频繁 ,所以标记-整理算法和标记算法常用于老年代的回收

 

分代收集就是根据对象生存周期的不同将内存划分几块,一般是将堆区分为新生代和老年代,然后根据这两个年代的不同特点分别使用上面的算法。

新生代对象大多生命周期较短,所以每次垃圾回收时都有大批对象死去,只有少量存活,这样就比较适合用复制算法,只需要付出少量的存活对象的复制成本就可以完成垃圾回收。

老年代对象大多生命周期较长,对象存活率高、而且没有额外内存空间对它进行分配担保,所以就需要使用标记算法或标记整理算法来进行垃圾回收。

 

当然像老年代和新生代的对象区分规则和内存分配担保机制等这次就先不说了,这次就写到这,欢迎交流
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值