v5内存分配器性能优化
背景
在之前我们提到采用自定义的内存分配器来解决防止频繁 make 导致的 gc 问题。gc 问题本质上是 CPU 消耗,而内存分配器本身如果产生了大量的 CPU 消耗那就得不偿失。经过测试初代内存分配器实现过于简单,产生了很多 CPU 消耗,因此必须优化内存分配器的性能。
性能消耗原因
在内存的分配和回收上,使用了简单的循环检测,当内存碎片较多的时候,循环查找消耗非常可观
查找可分配的内存
找到回收的内存偏移
性能优化
很快在社区中大家给出了一个称为 Buddy 的内存分片算法,那么这个算法是否能解决问题呢?
Buddy 算法
这是一个非常高效的算法,采用的是满二叉树数据结构,用一个数组来表示,然而当实际使用时却遇到了问题,因为我需要在自研的 BufReader 中使用,因此不能出现内存缝隙。Buffdy 算法在回收内存时只能按照申请什么回收什么的原则。举例,我申请了一个var a []byte = alloc(100)
,那么回收必须也是回收 free(a)
。而自研的 BufReader,需要“部分回收”能力。比如先回收a[50:]
,然后再回收a[:50]
。那么 Buddy 算法将无能为力。
当然,这个算法最终还会用到,这里先留个悬念。
双圣树模型
这是我自己起的名字,实际上是利用两颗平衡二叉树来实现快速找到可分配的内存以及快速回收内存。
type Allocator struct { pool []*Block sizeTree *Block offsetTree *Block Size int // history []History }
分配树
这颗树,用来快速查找可分配的内存,我们将可分配的内存用一个节点表示
type Block struct { Start, End int trees [2]Tree }
sizeTree 通过对每个节点的大小(End-Start)进行排序,在分配时,通过查找树中刚好大于等于待分配大小的节点,再修改这个节点,对树进行平衡即可。
回收树
这颗树,用来找到回收内存块前后的 Block,通过合并或者插入 Block 达到回收内存的效果。
| |
共享节点
由于两棵树只是表达了不同的排序,里面所有节点的数量和属性都是相同的,因此不需要两套节点,只需要公用一套节点集合即可。
type Tree struct { left, right *Block height int }
每个节点有两套指针,分别指向两棵树的不同的子节点,从而在逻辑上形成了两棵树。
进阶优化
虽然我们最终通过双圣树模型,实现了内存分配器的性能优化,但是优化并没有因此而停止。因为上述的内存分配器是无锁的,只适合给单个 goroutine 使用,如果加锁则性能大打折扣。那么从宏观角度来说,分配器持有的大内存块也会存在需要回收的情况。比如在流销毁的时候。
再次使用 Buddy 算法
这时候大内存块就不需要部分回收了,此时就又可以采用 Buddy 算法了。我们只需要在申请大内存块时,按照 2 倍数来申请,可以最大化利用。最终我们形成了两级内存分配。当然在这里就需要用锁了。
最终优化后性能得到大幅度提升
v5 版本通过 github.com/langhuihui/monibuca 切换到 v5 分支测试,或者gitee.com/m7s/monibuca。
进入仓库的 exsamle/default目录下运行 go run main.go即可体验。目前 v5 功能比较有限,目前仅能测试 rtmp 、hdl、webrtc 部分功能。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
一个 Clickhouse 集群磁盘损坏恢复数据的案例
通过一个故障案例,理解 ClickHouse 分布式机制。 作者:张宇,爱可生DBA,负责数据库运维和故障分析。擅长 ClickHouse、MySQL、Oracle,爱好骑行、AI、动漫和技术分享。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文约 1500 字,预计阅读需要 5 分钟。 业务场景 在日常运维的某个系统下,有一套 4 分片 3 副本的高可用分布式的 ClickHouse 集群。当前分片的每个节点的数据量为 5.6TB。 故障背景 监控发现其中的一个节点无法使用,后续排查发现 5 块磁盘已经损坏,Raid10 也无法保证数据完整,导致数据目录全部重新换成新的磁盘,而且使用的是传统机械盘,速度慢。现在联系厂商更换磁盘,需要停用此节点,等厂商更换完毕之后,需要配合恢复数据。 恢复思路 ClickHouse 的集群是一个分布式的集群,每个分片的数据不同,所有分片的数据加起来才是一份完整的数据,每个分片副本的数据是相同的,这就是 ClickHouse 数据的高可用。 本次也是非常典型的故障,硬件做了 Raid10,但是 Raid10 磁盘基本上...
- 下一篇
无鱼 v1.6.0 已经发布,项目工时系统
无鱼 v1.6.0 已经发布,项目工时系统 此版本更新内容包括: 工时系统专业版.v1.6.0 发布了 更新内容 增加了项目审核的设置 #I9F8GB 可在工时审核设置中,可选择由部门经理审核或者由项目经理审核。 未审核的日志,将不在项目日报、月报以及统计中显示。 2.增加了项目集功能 #I9NR52 3.优化了部分列表的详情界面,将详情页面更改为弹出新窗口方式。 4.优化了项目看板的操作方式,项目切换更流畅 5.部分删除操作增加了二次确认功能 6.优化了一些界面的尺寸问题。 修复了其他一些bug。 获取使用 安装部署:https://doc.wuyusoft.com/cost/5.install.html 下载 添加公众号 wuyusoft 或者扫码后关注,获取下载地址 详情查看:https://gitee.com/wy-soft/cost-pro/releases/v1.6.0
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G