需求

系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升。
比如nginx, 它在每个连接accept后会malloc一块内存,作为整个连接生命周期内的内存池。 当HTTP请求到达的时候,又会malloc一块当前请求阶段的内存池, 因此对malloc的分配速度有一定的依赖关系。(而apache的内存池是有父子关系的,请求阶段的内存池会和连接阶段的使用相同的分配器,如果连接内存池释放则请求阶段的子内存池也会自动释放)。

目标

内存管理可以分为三个层次,自底向上分别是:

本文主要介绍了glibc malloc的实现,及其替代品

一个优秀的通用内存分配器应具有以下特性:

现状

目前大部分服务端程序使用glibc提供的malloc/free系列函数,而glibc使用的ptmalloc2在性能上远远弱后于google的tcmalloc和facebook的jemalloc。 而且后两者只需要使用LD_PRELOAD环境变量启动程序即可,甚至并不需要重新编译。

glibc ptmalloc2

ptmalloc2即是我们当前使用的glibc malloc版本。

ptmalloc原理

系统调用接口


上图是 x86_64 下 Linux 进程的默认地址空间, 对 heap 的操作, 操作系统提供了brk()系统调用,设置了Heap的上边界; 对 mmap 映射区域的操作,操作系 统 供了 mmap()和 munmap()函数。
因为系统调用的代价很高,不可能每次申请内存都从内核分配空间,尤其是对于小内存分配。 而且因为mmap的区域容易被munmap释放,所以一般大内存采用mmap(),小内存使用brk()。

多线程支持

ptmalloc内存管理

  • 用户请求分配的内存在ptmalloc中使用chunk表示, 每个chunk至少需要8个字节额外的开销。 用户free掉的内存不会马上归还操作系统,ptmalloc会统一管理heap和mmap区域的空闲chunk,避免了频繁的系统调用。
  • ptmalloc 将相似大小的 chunk 用双向链表链接起来, 这样的一个链表被称为一个 bin。Ptmalloc 一共 维护了 128 个 bin,并使用一个数组来存储这些 bin(如下图所示)。

    数组中的第一个为 unsorted bin, 数组中从 2 开始编号的前 64 个 bin 称为 small bins, 同一个small bin中的chunk具有相同的大小。small bins后面的bin被称作large bins。

  • 当free一个chunk并放入bin的时候, ptmalloc 还会检查它前后的 chunk 是否也是空闲的, 如果是的话,ptmalloc会首先把它们合并为一个大的 chunk, 然后将合并后的 chunk 放到 unstored bin 中。 另外ptmalloc 为了提高分配的速度,会把一些小的(不大于64B) chunk先放到一个叫做 fast bins 的容器内。

  • 在fast bins和bins都不能满足需求后,ptmalloc会设法在一个叫做top chunk的空间分配内存。 对于非主分配区会预先通过mmap分配一大块内存作为top chunk, 当bins和fast bins都不能满足分配需要的时候, ptmalloc会设法在top chunk中分出一块内存给用户, 如果top chunk本身不够大, 分配程序会重新mmap分配一块内存chunk, 并将 top chunk 迁移到新的chunk上,并用单链表链接起来。如果free()的chunk恰好 与 top chunk 相邻,那么这两个 chunk 就会合并成新的 top chunk,如果top chunk大小大于某个阈值才还给操作系统。主分配区类似,不过通过sbrk()分配和调整top chunk的大小,只有heap顶部连续内存空闲超过阈值的时候才能回收内存。
  • 需要分配的 chunk 足够大,而且 fast bins 和 bins 都不能满足要求,甚至 top chunk 本身也不能满足分配需求时,ptmalloc 会使用 mmap 来直接使用内存映射来将页映射到进程空间。

ptmalloc分配流程

ptmalloc的缺陷

tcmalloc

tcmalloc是Google开源的一个内存管理库, 作为glibc malloc的替代品。目前已经在chrome、safari等知名软件中运用。
根据官方测试报告,ptmalloc在一台2.8GHz的P4机器上(对于小对象)执行一次malloc及free大约需要300纳秒。而TCMalloc的版本同样的操作大约只需要50纳秒。

小对象分配

CentralCache分配管理

回收

tcmalloc的改进

性能对比

官方测试

测试环境是2.4GHz dual Xeon,开启超线程,redhat9,glibc-2.3.2, 每个线程测试100万个操作。

上图中可以看到尤其是对于小内存的分配, tcmalloc有非常明显性能优势。

上图可以看到随着线程数的增加,tcmalloc性能上也有明显的优势,并且相对平稳。

github mysql优化

github使用tcmalloc后,mysql性能提升30%

Jemalloc

jemalloc是facebook推出的, 最早的时候是freebsd的libc malloc实现。 目前在firefox、facebook服务器各种组件中大量使用。

jemalloc原理


上图可以看到每个arena管理的arena chunk结构, 开始的header主要是维护了一个page map(1024个页面关联的对象状态), header下方就是它的页面空间。 Small对象被分到一起, metadata信息存放在起始位置。 large chunk相互独立,它的metadata信息存放在chunk header map中。

jemalloc的优化

性能对比

官方测试


上图是服务器吞吐量分别用6个malloc实现的对比数据,可以看到tcmalloc和jemalloc最好(facebook在2011年的测试结果,tcmalloc这里版本较旧)。

4.3.2 mysql优化
测试环境:2x Intel E5/2.2Ghz with 8 real cores per socket,16 real cores, 开启hyper-threading, 总共32个vcpu。 16个table,每个5M row。
OLTP_RO测试包含5个select查询:select_ranges, select_order_ranges, select_distinct_ranges, select_sum_ranges,

可以看到在多核心或者多线程的场景下, jemalloc和tcmalloc带来的tps增加非常明显。

参考资料

glibc内存管理ptmalloc源代码分析
Inside jemalloc
tcmalloc浅析
tcmalloc官方文档
Scalable memory allocation using jemalloc
mysql-performance-impact-of-memory-allocators-part-2
ptmalloc,tcmalloc和jemalloc内存分配策略研究
Tick Tock, malloc Needs a Clock

总结

在多线程环境使用tcmalloc和jemalloc效果非常明显。
当线程数量固定,不会频繁创建退出的时候, 可以使用jemalloc;反之使用tcmalloc可能是更好的选择。

几种常用内存管理底层介绍相关推荐

  1. Java GUI编程的几种常用布局管理器

    Java GUI编程的几种常用布局管理器 本人是一个大二的学生.因为最近有做JavaGUI界面的需求,因此重新开始熟悉JavaGUI的各种控件和布局.然后以次博文为笔记,总结.完善以及发表最近学习的一 ...

  2. ION内存管理器介绍

    1. ION介绍 ION是google在Android4.0为了解决内存碎片化管理而引入的通用内存管理器,用来支持不同的内存分配机制,如CARVOUT(PMEM),物理连续内存(kmalloc),虚拟 ...

  3. 国内4种常用日内CTA策略介绍及实现

    本文首发于微信公众号:优矿量化实验室.文章内容属作者个人观点,不代表和讯网立场.投资者据此操作,风险请自担. 本文将向大家介绍四种常见的CTA策略(Dual Thrust.R-Breaker.菲阿里四 ...

  4. Java 中几种常用的 RPC 框架介绍

    RPC是远程过程调用的简称,广泛应用在大规模分布式应用中,作用是有助于系统的垂直拆分,使系统更易拓展.Java中的RPC框架比较多,各有特色,广泛使用的有RMI.Hessian.Dubbo等.RPC还 ...

  5. 公司常用协同管理软件介绍

    1.redmine redmine是一款基于web的BUG管理软件,通过WEB形式把成员.任务.文档.讨论以及各种形式的资源组织在一起,推动项目的进度,可对接版本管理系统GIT.SVN等获取版本变更信 ...

  6. 测试儿童智力软件开发,四种常用儿童智力测试办法介绍

    [ 摘要 ]现今世界上有不下百种儿童智力测试表或软件.这些测试表有测验孩子综合性能力的,也有单独测试智力的.面对市场上各种各样的智力测试,普通的群众根本无法判断其是否有效. 筛查性智力测验 (无法得知 ...

  7. 工作常用工作管理软件介绍

    jira: 先给个官方的让人搞不懂的解释:JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪.客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域.而实际上 ...

  8. Java中几种常用的RPC框架介绍

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 关注订阅号「程序员小乐」,收看更多精彩内容 每日英文 Crouch down ...

  9. Executors框架——5种常用的线程池介绍及区别

    1. CachedThreadPool线程池(可向下转型为ThreadPoolExecutor) 1.1 线程池核心线程数是0,说明线程空闲时,会被自动回收. 1.2 任务队列只能有一个任务,而且最大 ...

最新文章

  1. 1021 Deepest Root
  2. Python最抢手、Go最有前途,7000位程序员揭秘2019软件开发现状
  3. 【译】使用 Python 编写虚拟机解释器
  4. 黑马程序员之单例模式学习
  5. 面试官:DDD如何指导微服务拆分?90%的程序员都答不上来!
  6. c++调用cplex求解例子_Java调用cplex求解运输问题
  7. Taro+react开发(61) 一条虚线
  8. 失业状态,整理一下近期的面试问题 -- 直面自我
  9. SpringMVC中404错误解决方法总结
  10. Java学习笔记-12.传递和返回对象
  11. Spring AOP面向切面源码解析
  12. 基于SSM的选课系统
  13. 轻量级Java EE企业应用实战(第4版) Struts 2+Spring 4+Hibernate整合开发 含CD光盘1
  14. 计算机禁止安装游戏,win7系统禁用自动安装游戏应用的详细教程
  15. 突破淘宝对于 selenium 检测
  16. 无线ap的ntp服务器,怎么配置cisco路由器的NTP
  17. 大连新知源09年3月RHCE考试通过率90.9% —— 注重能力培养
  18. 你有旧iPhone吗?快来瓜分苹果1800万赔偿款!
  19. 怎样改变照片大小?免费在线图片压缩方法
  20. oracle数据库课后习题答案,oracle数据库经典练习题及答案

热门文章

  1. 如何远程管理天翼云RDS数据库
  2. PageNow企业级数据可视化开发平台
  3. python unit test什么意思_Pycharm上python和unittest两种姿势傻傻分不清楚
  4. Nginx 入门指南
  5. LabVIEW使用VI Server的时候出现1003错误
  6. Java体系十大组织
  7. javajavaScript常见校验器
  8. 编写程序,由键盘输入三个整数分别存入变量num1,num2,num3中,对它们进行排序, 使用if-else结构,并按从小到大的顺序输出
  9. HTML5标签-按功能分类整理
  10. python随机生成英文字母_在Python中生成随机字母