深入浅出 Golang 内存管理
了解内存管理~
前言:
本节课主要介绍了内存管理知识与自动内存管理机制,并对目前 Go 内存管理过程中存在的问题提出了解决方案,同时结合了上次课程学习的《Go 语言性能优化》相关知识,提供可行性的优化建议 …
自动内存管理
Go 语言作为相对新型的语言,自动内存管理肯定是少不了的了,和 Java 一样,Go 语言也有垃圾回收机制,可以实现自动内存管理,下面让我们来了解一些自动内存管理的相关知识。
🎈自动内存管理的概念:
程序运行时的内存分配策略有很多种:单一连续分配、固定分区分配、动态分区分配,现代的程序一般采用动态分区分配,会根据程序在运行时的需求动态地分配内存(malloc()
),将动态分配地内存称作动态内存。
自动内存管理是指由程序语言地运行时系统管理动态内存。
- 避免手动内存管理,专注于实现业务逻辑;
- 保证内存使用的正确性和安全性。
自动内存管理也可以叫垃圾回收(GC),主要负责:
- 为新对象分配空间;
- 找到存活对象;
- 回收死亡对象的内存空间。
GC 相关概念
- Mutator:业务线程,分配新对象,修改对象指向关系;
- Collector:GC 线程,找到存活对象,回收死亡对象的内存空间;
- Serial GC:只有一个 Collector 的 GC 算法;
- Parallel GC:支持多个 Collectors 同时回收的 GC 算法;
- Concurrent GC:Mutator(s) 和 Collector(s) 可以同时执行的 GC 算法。
🎯评价 GC 算法的几大指标:
- 安全性:不能回收存活的对象;
- 吞吐率:用来衡量 GC 时间的占比,其值为
1 - GC 时间 / 程序执行总时
; - 暂停时间:GC 可能会导致暂停业务,一般希望暂停时间越短越好;
- 内存开销:GC 元数据开销。
在学习 Go 内存管理之前,我们先来了解一下垃圾回收的几种实现方案~
追踪垃圾回收
追踪垃圾回收是 GC 策略的其中一种,属于间接式的回收策略,这种策略不会直接寻找垃圾本身,而是先去找到存活的对象,然后反过来判断其余的对象应该被回收掉。
✔追踪垃圾回收的步骤:
- 标记根对象:静态变量、全局变量、常量、线程栈等;
- 标记:从根对象出发,找到所有可达对象;
- 清理:回收掉所有不可达对象。
- 将存活对象复制到另外的内存空间(Copying GC)
- 将死亡对象的内存标记为“可分配”(Mark-sweep GC)
- 移动并整理存活对象(Mark-compact GC)
(根据对象的生命周期,会使用不同的标记和清理策略)
分代 GC(Generational GC)
分代 GC 是基于分代假说的内存管理策略,是一种比较常见的策略。
弱分代假说认为绝大多数对象都是朝生夕灭的,生命很短;强分代假说认为活得越久也就是熬过越多次垃圾收集过程的对象就越难以消亡,这两个分代假说共同奠定了垃圾回收的设计原则。
分代 GC 策略会给每个对象一个年龄(经历过 GC 的次数),将对象分成老年代和年轻代,把不同年龄的对象放在堆内存(Heap)的不同区域,为其制定不同的 GC 策略,从而降低整体内存管理的开销。
-
年轻代(Young generation)
- 常规的对象分配
- 由于存活对象很少,可以采用 copying collection 策略
- GC 吞吐率很高
-
老年代(Old generation)
- 对象趋向于一直存活,反复复制开销较大
- 可以采用 mark-sweep collection 策略
引用计数(ARC)
引用计数是另一种 GC 策略,在这种策略下,每个对象都有一个与之关联的引用数目,只有引用数大于 0 的对象才存活。
⭐引用计数的优点:
- 内存管理的操作被平摊到程序的执行过程中;
- 内存管理不需要了解 runtime 的实现细节。
👎引用计数的缺点:
- 维护引用计数的开销较大:通过原子操作保证对引用计数操作的原子性和可见性;
- 无法回收环形数据结构(循环引用) —— weak reference;
- 额外的内存开销:每个对象都引入额外的内存空间存储引用数目;
- 回收内存时依然可能引发暂停。
✨引用计数 vs. 其他策略:
时机 | 性能 | 延迟 | |
---|---|---|---|
ARC | 引用计数为 0 马上回收 | 快 | 小 |
other GC | 定时扫描清理 | 慢 | 大 |
Go 内存分配
Go 的内存分配基于两个思想:分块 & 缓存。
分块
Go 会提前将内存分块,给对象分配内存时会找一个尺寸最接近的块分配。
🎯目标: 为对象在堆(heap)上分配内存。
✔内存分块:
- 调用系统调用
mmap()
向 OS 申请一大块内存,例如 4MB; - 先将内存划分成大块,例如 8KB,称作 mspan;
- noscan mspan:分配不包含指针的对象(GC 不需要扫描)
- scan mspan:分配包含指针的对象(GC 需要扫描)
- 再将大块继续划分成特定大小的小块,用于对象分配。
🍬对象分配: 根据对象的大小,选择最合适的块返回。
缓存(cache)
Go 的内存分配器为内存做了多级不同的缓存,从而加快整体的内存分配速度。
线程缓存分配(Thread-Caching Malloc,TCMalloc)是用于分配内存的机制,Go 语言的内存分配器就借鉴了 TCMalloc 的设计实现高速的内存分配,它的核心理念是使用多级缓存将对象根据大小分类,并按照类别实施不同的分配策略。
☕分配过程:
- 分配内存是指给 goroutine(简称为 g) 上的一段代码分配内存,g 会先绑定在 p(Go 线程)上;
- 每个 p 包含一个 mcache 用于快速分配,用于为绑定与 p 上的 g 分配对象;
- mcache 管理一组 mspan;
- 当 mcache 中的 mspan 分配完毕,向 mcentral 申请带有未分配块的 mspan;
- 当 mspan 中没有分配的对象,mspan 会被缓存在 mcentral 中,而不是立刻释放并归还给 OS。
Go 语言中的 GC 策略
了解了这么多内存管理的相关知识和垃圾回收策略,下面来一起看看 Golang 中采用的垃圾回收策略。
Go 语言的垃圾回收总体采用的是经典的 mark-sweep 算法,Go 语言的版本不同,采用的 GC 策略可能是不一样的。Go 1.5 正在实现的垃圾回收器是 “非分代的、非移动的、并发的、三色的标记清除垃圾收集器”。
Go 1.5 使用的三色标记法可以看成 mark-sweep 的增强版,这种方法的 mark 操作是可以渐进执行的而不需每次都扫描整个内存空间,,可以减少 stop the world(STW)的时间;分代 GC 策略在上文已经提及,但是 Go 1.5 还暂时没有采用,Go 官方表示会在 1.6 版本的 GC 优化中考虑~
随着 Golang 的推陈出新,Go 的垃圾回收性能一直在提升,但目前距离 Java 语言的 JVM 使用的成熟的垃圾回收系统还有一定差距。
Go 内存管理优化
Go 内存分配机制中的问题
对象分配是非常高频的操作,每秒分配 GB 级别的内存,小对象占比又比较高,加上分配路径长,这就导致 Go 内存分配比较耗时。
- 分配路径长:
g->m->p->mcache->mspan->memory block->return pointer
pprof()
:对象分配的函数是最频繁调用的函数之一
字节的优化方案:Balanced GC
Balanced GC 是字节跳动官方推出的针对 Go SDK 里面对象分配做的优化方案。
- 每个 g 都绑定一大块内存(1KB),称作 goroutine allocation buffer(GAB);
- GAB 用于 noscan 类型的小对象分配:
< 128 B
; - 使用三个指针维护 GAB:base,end,top;
- Bump pointer(指针碰撞)风格对象分配:无须和其他分配请求互斥,分配动作简单高效。
// 一次对象分配:
if top + size <= end {addr := toptop += sizereturn addr
}
💭技术细节:
GAB 对于 Go 内存管理来说是一个大对象。
- 本质:将多个小对象的分配合并成一次大对象的分配。
- 问题:GAB 的对象分配方式会导致内存被延迟释放。
- 方案:移动 GAB 中存活的对象(用 copying GC 的算法管理小对象)
- 当 GAB 总大小超过一定阈值时,将 GAB 中存活的对象复制到另外分配的 GAB 中;
- 原先的 GAB 可以释放,避免内存泄漏。
Balanced GC 作为语言层面的性能优化,开启以后可以减少 CPU 负荷,降低核心接口时延,获得不错的性能收益。
相关文章:

深入浅出 Golang 内存管理
了解内存管理~ 前言: 本节课主要介绍了内存管理知识与自动内存管理机制,并对目前 Go 内存管理过程中存在的问题提出了解决方案,同时结合了上次课程学习的《Go 语言性能优化》相关知识,提供可行性的优化建议 … 自动内存管理 Go…...

基于Python的简单40例和爬虫详细讲解(文末赠书)
目录 先来看看Python40例 学习Python容易坐牢? 介绍一下什么是爬虫 1、收集数据 2、爬虫调研 3、刷流量和秒杀 二、爬虫是如何工作的? 三、爬虫与SEO优化 什么是python爬虫 Python爬虫架构 最担心的问题 本期送书 随着人工智能以及大数据的兴起…...

Vector - CAPL - CAN x 总线信息获取(续2)
继续.... 目录 ErrorFrameCount -- 错误帧数量 代码示例 ErrorFrameRate -- 错误帧速率 代码示例 ExtendedFrameCount -- 扩展帧数量 代码示例 ExtendedFrameRate -- 扩展帧速率 代码示例 ExtendedRemoteFrameCount -- 远程扩展帧数量 代码示例 ExtendedRemoteFrameRa…...
C++基础知识【8】模板
目录 一、什么是C模板? 二、函数模板 三、类模板 四、模板特化 五、模板参数 六、可变模板参数 七、模板元编程 八、嵌套模板 九、注意事项 一、什么是C模板? C模板是C编程中非常重要的一部分,它允许程序员以一种通用的方式编写代码…...

MAC-安装Java环境、JDK配置、IDEA插件推荐
背景:发现经常换电脑装环境等比较麻烦,主要还是想记录一下,不要每次安装都到处翻。。 1、下载并安装JDK 到官网下载所需的JDK:https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html 这儿下…...
Mysql如何避免常见的索引失效
Mysql索引算是非常常用了,用得好提高效率,用的不好适得其反 如何避免常见的索引失效 1.模糊查询 使用 LIKE 查询时,如果搜索表达式以通配符开头,如 %value,MySQL 就无法使用索引来加速查询,因为它无法倒序…...

SpringBoot集成Redis及问题解决
SpringBoot集成Redis 此篇文章为SpringBoot集成Redis的简单介绍,依赖、序列化操作、工具类都可以在后面的实操中直接搬运使用或者在此基础上进行改进使用 1、集成Redis 1.1、新建SpringBoot项目 新建项目这边就不一一介绍了,大家如果还有不会的可以自行…...
PyTorch 人工智能研讨会:6~7
原文:The Deep Learning with PyTorch Workshop 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心…...

AI绘图设计师Stable Diffusion成为生产力工具(五):放大并修复老照片、马赛克照片、身份证件照
S:你安装stable diffusion就是为了看小姐姐么? I :当然不是,当然是为了公司的发展谋出路~~ 预先学习: 安装webui《Windows安装Stable Diffusion WebUI及问题解决记录》。运行使用时问题《Windows使用Stable Diffusion时…...
cubase正版下载安装包-cubase正版下载v1.2.0.69 软件激活版
cubase正版下载是一款实用的音乐创作类软件。我们可以通过这款软件实现创作音乐的自由,再也不用花大价钱请别人来帮忙制作,只需自己动动手就可以轻松完成我们所想要的,这款软件做到了让每一位热爱音乐的人都可以实现自己的梦想。 cubase正版…...
Python机器学习:支持向量机
这是我读本科的时候第一个接触到的机器学习算法,但也是第一个听完就忘的。。。 他的基本思想很简单:想办法把一个样本集划成两个部分:对于空间中的样本点集合,我们找到一个超平面把这个样本点集合给分成两个部分,其中…...

矩阵和线性代数的应用
矩阵和线性代数是数学中重要的概念,它们被广泛应用于物理、工程、计算机科学、经济学等众多领域。本文将讨论矩阵和线性代数的一些基本概念以及它们在实际应用中的重要性和影响。 一、矩阵和线性代数的基本概念 矩阵是由数字组成的矩形数组。它可以表示线性方程组…...

六:内存回收
内存回收: 应用程序通过 malloc 函数申请内存的时候,实际上申请的是虚拟内存,此时并不会分配物理内存。 当应用程序读写了这块虚拟内存,CPU 就会去访问这个虚拟内存, 这时会发现这个虚拟内存没有映射到物理内存&…...

【cpolar 内网穿透】Openwrt 软路由实现内网穿透
cpolar 是一种安全的内网穿透云服务,它将内网下的本地服务器通过安全隧道暴露至公网。使得公网用户可以正常访问内网服务。 文章目录 前言一、上传 cpolar 安装包二、配置cpolar环境变量三、安装并配置 cpolar 服务3.1 安装 cpolar3.2 启动 cpolar3.3 进行其他配置 …...
Android 10.0 Camera2 拍照功能默认选前摄像头
1.概述 在10.0的系统产品开发中,对于app调用系统api来打开摄像头拍照的功能也是常有的功能,而拍照一般是默认打开后置摄像头拍照的,由于 客户的产品特殊要求,需要打开前置摄像头拍照功能,所以需要了解拍照功能的流程,然后修改默认前置摄像头打开拍照功能就可以了 app调…...

vue-vue2和vue3的diff算法
核心要点 数据变化时,vue如何更新节点虚拟DOM 和 真实DOM 的区别vue2 diff 算法vue3 diff 算法 一、 数据变化时,vue如何更新节点 首先渲染真实DOM的开销是很大,比如有时候我们修改了某个数据且修改的数据量很大时,此时会频繁的…...

一文解读基于PaddleSeg的钢筋长度超限监控方案
项目背景 钢铁厂生产钢筋的过程中会存在部分钢筋长度超限的问题,如果不进行处理,容易造成机械臂损伤。因此,需要通过质检流程,筛选出存在长度超限问题的钢筋批次,并进行预警。传统的处理方式是人工核查,该方…...

NumPy 数组学习手册:1~5
原文:Learning NumPy Array 协议:CC BY-NC-SA 4.0 译者:飞龙 一、NumPy 入门 让我们开始吧。 我们将在不同的操作系统上安装 NumPy 和相关软件,并查看一些使用 NumPy 的简单代码。 正如“序言”所述,SciPy 与 NumPy 密…...

【C++11】晦涩难懂语法系列:可变参数模板
目录 可变参数模板 1.1 概念 1.2 可变参数模板定义 1.3 参数包的展开方式 1.3.1 递归展开参数包 1.3.2 逗号表达式展开参数包 1.4 STL的emplace系列函数 可变参数模板 1.1 概念 在C语言阶段,我们已经接触过可变参数,比如scand、printf等等 这里…...

计算机组成原理第二章——数据的表示与运算(下)
提示:时光清浅处 一步一安然 文章目录 前言2.3.1 浮点数的表示2.3.2 IEEE7542.2.3 浮点数的运算 前言 本节主要讲三个问题,浮点数的表示,IEEE 754标准,浮点数的加减运算 2.3.1 浮点数的表示 浮点数的作用和基本原理 定点数可表…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...

什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...