当前位置: 首页 > news >正文

- 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》

         本文属于专栏《构建工业级QPS百万级服务》​​​​​        


 1、前置知识        

        c++的内存管理,主要说的是堆内存管理。现代计算机系统中,用户进程的堆内存,由内核映射。

  • 堆内存的来源
    •  主要是通过mmap()函数,在进程的虚拟地址空间中创建新的映射
  •  为什么需要malloc
    •  因为mmap()是按照page size(一般是4096字节)分配的,如果是程序员直接使用很容易照成浪费,高效地使用内存,是共同需求,所以有了malloc
  • 为什么需要tcmalloc和jemalloc
    •  malloc在内存碎片和多线程性能方面做得不好
  • 三方的内存管理库运行原理,就是alias malloc和free函数以及operator new(注意不是new operator)
#define ALIAS(tc_fn)   __attribute__ ((alias (#tc_fn), used))extern "C" { void* malloc(size_t size) __THROW               ALIAS(tc_malloc);void free(void* ptr) __THROW                    ALIAS(tc_free);
}   // extern 
  • 两个常用的内存分配算法
    •  Buddy allocation:连续的内存,分配时不断折半,直到刚好满足需要的内存
    • Slab allocation:将内存管理起来,分成很多个大小相同的小片,用一个管理类去记录内存的分配和释放

2、TCMalloc(Thread Cache Malloc)

  • 实现原理:
  • 首先,glibc中,内存分配相关的函数都是弱符号,TCMalloc定义了自己的函数并将其覆盖
    • 主要思想是每个线程有自己的缓存,在自己线程缓存不够用时,找Central Heap
    • 内存分配时,不同大小有不同的策
      • 小内存:
        • 每个线程缓存有一个单链表,每个节点后面跟着的也是一个链表,如下图,calss0 位8bytes,class1为16bytes,class2为32bytes。当thread cache不够,就找central heap,当central heap不够,就找内核分配。如果Thread Cache的链太短,会频繁找去central分配(自旋锁),如果太长会浪费一些空间
        • tcmalloc_max_total_thread_cache_bytes参数表示的是在当前thread cache中,最多的缓存的不释放回central cache的内存。设置太低会导致在高qps的服务中,有频繁释放和申请小内存时,会和central cache交互频繁,导致加锁太多
        • 为了设置合适的free list(class 0 后面跟着的链表)长度,使用了慢启动算法来决定每个独立的free list的链表长度,频繁的申请会增加长度,频繁的释放会抑制长度
      • 中内存CentralCache(256kb <= size <= 1MB)
        • 这里的个page为8kb
      • 大内存PageHeap,从pageHeap中找,如果没有就向OS申请
      • 调优化经验
        • 对于应用使用堆内存量大的,如几个G甚至上百G的。虽然版本不同,但是一般给每个线程默认管理的内存大小不超过100M。所以在高配置应用中,使用TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES来增加单个线程可管理的内存是有显著性能提升的。如:export TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=1073741824

3、JeMalloc

  • 与tcmalloc类似,只是中内存不是从central heap中取,还是从线程的缓存中取,jemalloc的线程缓存管理范围更广,更复杂,但是效率更高
  • 原理
    • 几个名词
      • page ,操作系统提供的内存,来自于mmap
      • chunk,jemalloc申请内存的大小单位,是page size的n倍,默认2Mb
      • base,jemalloc自身使用的堆内存结构
      • arena,jemalloc最重要的部分,内存管理器(每个线程一个),分配算法是Buddy和Slab的组合
        • chunk 使用buddy算法划分不同的run,run使用不同的算法划分固定大小的region,大部分内存分配直接查找对应的run,从中分配空闲的region
      • bin:bin管理相同类型的run,记录了run相关信息。用红黑树管理有空闲的region的run,并按照地址排序
    • 分配流程
      • small内存去bin管理的内存中找,bin找不到再去arena管理的内存找
      • large的直接去arena中找
      • huge也是去arena找,只是这里用的是线程共享的arena,但是这里频率很低,影响小

          所以一般来说,频繁创建和删除线程的使用tcmalloc,用固定线程的使用jemalloc效率更高。

相关文章:

  • win10下wsl2使用记录(系统迁移到D盘、配置国内源、安装conda环境、配置pip源、安装pytorch-gpu环境、安装paddle-gpu环境)
  • 【nginx实践连载-2】多应用安装部署
  • 计算机设计大赛 深度学习YOLO抽烟行为检测 - python opencv
  • 代码随想录刷题笔记 DAY 28 | 复原 IP 地址 No.93 | 子集 No.78 | 子集 II No.90
  • 【STM32 CubeMX】SPI层次结构SPI协议与SPI控制器结构
  • JWT登录验证前后端设计与实现笔记
  • c# B树
  • 记录 | 验证pytorch-cuda是否安装成功
  • 【天幕系列 02】开源力量:揭示开源软件如何成为技术演进与社会发展的引擎
  • Apache 神禹(shenyu)源码阅读(一)——Admin向Gateway的数据同步(Admin端)
  • 【深度学习:DICOM 注释工具】在 DICOM 注释工具中寻找的 7 个功能
  • 【论文精读】GPT2
  • Excel练习:折线图突出最大最小值
  • 第二十九回 施恩三入死囚牢 武松大闹飞云浦-分布式版本控制系统Git使用
  • Html的<figure><figcaption>标签
  • [LeetCode] Wiggle Sort
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • CentOS7 安装JDK
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • github从入门到放弃(1)
  • JavaScript函数式编程(一)
  • Javascript设计模式学习之Observer(观察者)模式
  • js继承的实现方法
  • Laravel 中的一个后期静态绑定
  • leetcode-27. Remove Element
  • Linux快速复制或删除大量小文件
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • 初探 Vue 生命周期和钩子函数
  • 将 Measurements 和 Units 应用到物理学
  • 那些年我们用过的显示性能指标
  • 盘点那些不知名却常用的 Git 操作
  • 试着探索高并发下的系统架构面貌
  • ​Spring Boot 分片上传文件
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (二)Linux——Linux常用指令
  • (二开)Flink 修改源码拓展 SQL 语法
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (论文阅读40-45)图像描述1
  • (转) ns2/nam与nam实现相关的文件
  • (转)菜鸟学数据库(三)——存储过程
  • .gitignore
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET中winform传递参数至Url并获得返回值或文件
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • [20150321]索引空块的问题.txt
  • [ACM] hdu 1201 18岁生日
  • [bzoj2957]楼房重建
  • [CSS3备忘] transform animation 等
  • [GN] Vue3.2 快速上手 ---- 核心语法2