自动内存管理 | 青训营笔记

161 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第13篇笔记

😆在这里,我对今天所新学到的自动内存管理做了一次总结

😜Golang的其他知识在哪里找呢,那你就问对了

👨‍💻Golang基础复习 - 掘金 (juejin.cn) 在这里我总结了一些这篇文章没有提到的一些知识

😊如果有小伙伴能想到更多知识,欢迎大家在评论区留言,那么我们就开始吧

👩‍💻👨‍💻哟西,一个棕~

😎😎😎我是小小分割线

介绍

概念:

  1. 动态内存:

    程序在运行时根据需求所动态分配的内存

  2. 自动内存管理(垃圾回收):

    由程序语言的运行时系统来管理动态内存

    优点:

    避免手动管理内存,专注于实现业务逻辑

    保证内存使用的正确性和安全性

自动内存管理的主要的核心任务

  1. 为新对象分配空间

  2. 找到存活的对象

  3. 回收死亡的对象的内存空间

自动内存的相关概念

  • Mutator:业务线程

    执行业务,分配新对象,修改对象的指向关系

  • Collector:GC线程

    找到存活的对象,回收死亡的对象


  • Serical GC

    只使用一个Collector去回收

  • Parallel GC

    使用多个Collector去回收

  • Concurrent GC

    Mutator和Colletor可以同时执行

    条件:

    由于Mutator和Collector同时执行,所以可能Mutator在运行时,有的对象会改变指向

    此时要求Collector必须能够感知对象指向关系的改变

image.png

评价GC算法

安全性:不能回收未死亡的的对象

吞吐率:花在GC上的时间(1-(GC时间/程序执行时间))

暂停时间:业务暂停的时间 stop the world(stw)

内存开销:GC元数据的开销

追踪垃圾管理 Tracing GC

原则条件:指针指向关系为不可达的对象可以被回收

执行步骤:

  1. 标记根对象(静态变量,全局常量,常量,线程栈等等)

  2. 通过标记找到所有可达对象

  3. 清理所有不可达对象

清理对象的策略

要根据对象的生命周期,使用不同的标记和清理策略

Copying GC

将所以存活的对象都复制到另外的内存空间

image.png

Mark-sweep GC

使用free list管理空闲内存

将所有死亡的对象用标记标出来,以后就可以直接使用这块空间覆盖上去

image.png

Compact GC

和Copying类似,但是是原地整理对象

根据策略进行压缩

image.png

分代GC Generational GC

也就是分年代来进行不同策略

image.png

原理是:分代假说(most objects die young)

就是大多对象很年轻就会死亡

简单来说就是用的久的对象不容易不用

每个对象都有年龄:经历GC的次数

在年轻代中由于存活对象很少,可以采用Copying

在老年代中由于对象一直趋向活着,复制开销大,可以使用mark-sweep

引用技术 Reference counting

原理是:给每一个对象都由一个与之关联的引用数目

对象存活的条件:有引用并且引用数大于0

优点:

  1. 内存管理的操作被平摊到程序执行过程中了

  2. 内存管理不需要了解runtime的实现细节

缺点:

  1. 维护引用的开销较大

    由于可能会有多个线程操作同一个对象,我们要通过原子操作保证对引用计数操作的原子性和可见性

  2. 无法回收环形数据结构(有解决方法)

image.png

  1. 需要额外的内存开销用于存储计数

  2. 回收大内存时还是可能会引发暂停


以上就是我总结在今天的内存管理课学到的知识

😎😎😎又是我,我还是小小分割线

都用心看到这里了,那就求个赞吧😘

🥳🥳🥳如果小伙伴有其他的小知识,一定不要忘了在评论区讨论哟,多多讨论,生态才会越来越好