TCMalloc详解


本文部分内容是结合参考其他文章已经tcmalloc官方文档。

TCMalloc

​ TCMalloc 是 Google 对 C 的 malloc() 和 C++ 的 operator new 的自定义实现,用于在我们的 C 和 C++ 代码中进行内存分配。 TCMalloc 是一种快速、多线程的 malloc 实现。

​ TCMalloc为每个线程分配了缓存,这个缓存是线程私有的,可以减少多线程程序竞争。对于小对象的内存分配,首先会去请求线程缓存,不用加锁,如果缓存不能满足的话,需要去向后面的内存存储结构中获取,此时需要加锁获取,因为其他线程可能正在获取内存空间,但是大部分情况下线程缓存就可以满足内存请求,所以几乎不需要锁。对于大对象的内存分配,TCMalloc尝试着使用细粒度和高效的自旋锁。另外一个TCMalloc的好处是小对象内存分配效率高。例如,分配n个8 byte的对象时,使用大约8n * 1.01byte的空间,只有百分之一的空间浪费。ptmalloc2分配内存的方法为每个对象使用一个4 byte的标头,并且将大小四舍五入为8 byte的倍数,最终使用16n byte。

虚拟内存

​ 有一个结论需要提一下,我们的进程是运行在虚拟内存上的,图示如下:

在这里插入图片描述

  • 对于我们的进程而言,可使用的内存是连续的

  • 安全,防止了进程直接对物理内存的操作(如果进程可以直接操作物理内存,那么存在某个进程篡改其他进程数据的可能)

  • 虚拟内存和物理内存是通过MMU(Memory Manage Unit)映射的(感兴趣的可以研究下)

  • 等等(感兴趣的可以研究下)

    所以,以下文章我们所说的内存都是指虚拟内存

TCMalloc架构

​ 下面这幅图粗略的介绍了TCMalloc的内部结构:

在这里插入图片描述

​ 我们可以将TCMlloc分为三部分,front-end, middle-end, back-end。 它们的职责分别是:

  • Front-end是一个缓存,提供内存快速分配和重分配内存给应用程序的功能。它主要有2部分组成:Per-thread cache和Per-CPU cache。这里只聊 Per-thread模式。
  • Middle-end负责给front-end提供缓存。当front-end缓存不足时,首先从middle-end中获取。它由Central free list组成。
  • Back-end负责从系统获取内存。当middle-end中的内存不足时,从back-end中获取。它主要设计page heap的内容。

​ 注意一下,front-end可以在per-cpu或者legacy per-thread模式下运行,后端可以支持hugepage aware pageheap或者legacy pageheap。

TCMalloc Front-end

Front-end可以处理特定大小的内存分配请求。Front-end有一个线程缓存,可用于分配或保存空闲内存。这个缓存一次只能被一个线程访问,所以它不需要任何锁,因此大多数分配和释放都很快。

​ 如果Front-end具有适当大小的内存缓存,可以直接从缓存中为程序分配对象。如果该特定大小的内存块为空,则Front-end将从Middle-end请求一批内存以重新填充缓存。中端包括 CentralFreeListTransferCache

​ 如果Middle-end可用的内存空间耗尽,或者请求的大小大于Front-end缓存的最大大小,则请求会去Back-end中获取内存,或者重新填充Middle-end的内存。后端也称为 PageHeap。

​ TCMalloc 前端有两种实现:

  • 最初它支持对象的每线程缓存(因此得名Thread-local malloc

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值