ptmalloc,tcmalloc和jemalloc内存分配策略研究
转载:https://cloud.tencent.com/developer/article/1173720
操作系统内存布局
各种malloc的内存分配管理方式离不开操作系统的内存布局策略。
32位经典内存布局
32位系统下经典内存布局如上,程序起始的1GB地址为内核空间,接下来是向下增长的栈空间和由0x40000000向上增长的mmap地址。而堆地址是从底部开始,去除ELF、数据段、代码段、常量段之后的地址并向上增长。但是这种布局有几个问题,首先是容易遭受溢出攻击;其次是,堆地址空间只有不到1G有木有?如果mmap内存比较少地址很浪费有木有?所以后来就有了另一种内存布局。
32位默认内存布局
这幅图描述地比较清楚也比较完整。首先是加入了几种Random offset随机偏移,导致内存溢出攻击不那么容易了,其次是堆仍然向上,但是mmap向下增长。但是这样的话栈空间就不是动态增长的了,所以现在的操作系统都有栈大小限制来着(Windows好像默认是2MB对吧?Linux可以ulimit –s查看)。这种内存布局地址利用度比较高。
64位内存布局
64位系统的寻址空间比较大,所以仍然沿用了32位的经典布局,但是加上了随机的mmap起始地址,以防止溢出攻击。反正一时半会是用不了这么大的内存地址了,所以至少N多年不会变了(话说要生产出40TB+的内存条,把堆内存地址用光,一时半会也搞不定吧)。
总结
纵观各种内存布局,对于大内存各种malloc基本上都是直接mmap的。而对于小数据,则通过向操作系统申请扩大堆顶,这时候操作系统会把需要的内存分页映射过来,然后再由这些malloc管理这些堆内存块,减少系统调用。而在free内存的时候,不同的malloc有不同的策略,不一定会把内存真正地还给系统,所以很多时候,如果访问了free掉的内存,并不会立即Run Time Error,只有访问的地址没有对应的内存分页,才会崩掉。
Ptmalloc
Ptmalloc采用主-从分配区的模式,当一个线程需要分配资源的时候,从链表中找到一个没加锁的分配区,在进行内存分配。
小内存分配
在ptmalloc内部,内存块采用chunk管理,并且将大小相似的chunk用链表管理,一个链表被称为一个bin。前64个bin里,相邻的bin内的chunk大小相差8字节,称为small bin,后面的是large bin,large bin里的chunk按先大小,再最近使用的顺序排列,每次分配都找一个最小的能够使用的chunk。
Chunk的结构如上所示,A位表示是不是在主分配区,M表示是不是mmap出来滴,P表示上一个内存紧邻的chunk是否在使用,如果没在使用,则size of previous chunk是上一个chunk的大小,否则无意义(而且被用作被分配出去的内存了),正式根据P标记位和size of previous chunk在free内存块的时候来进行chunk合并的。当然,如果chunk空闲,mem里还记录了一些指针用于索引临近大小的chunk的,实现原理就不复述了,知道大致作用就行。
在free的时候,ptmalloc会检查附近的chunk,并尝试把连续空闲的chunk合并成一个大的chunk,放到unstored bin里。但是当很小的chunk释放的时候,ptmalloc会把它并入fast bin中。同样,某些时候,fast bin里的连续内存块会被合并并加入到一个unsorted bin里,然后再才进入普通bin里。所以malloc小内存的时候,是先查找fast bin,再查找unsorted bin,最后查找普通的bin,如果unsorted bin里的chunk不合适,则会把它扔到bin里。
大内存分配
Ptmalloc的分配的内存顶部还有一个top chunk,如果前面的bin里的空闲chunk都不足以满足需要,就是尝试从top chunk里分配内存。如果top chunk里也不够,就要从操作系统里拿了。
还有就是特别大的内存,会直接从系统mmap出来,不受chunk管理,这样的内存在回收的时候也会munmap还给操作系统。
简而言之,就是:**
**小内存: [获取分配区(arena)并加锁] -> fast bin -> unsorted bin -> small bin -> large bin -> top chunk -> 扩展堆
大内存: 直接mmap
总结
释放的时候,几乎是和分配反过来,再加上可一些chunk合并和从一个bin转移到另一个bin的操作。并且如果顶部有足够大的空闲chunk,则收缩堆顶并还给操作系统。
介于此,对于ptmalloc的内存分配使用有几个注意事项:
- Ptmalloc默认后分配内存先释放,因为内存回收是从top chunk开始的。
- 避免多线程频繁分配和释放内存,会造成频繁加解锁。
- 不要分配长生命周期的内存块,容易造成内碎片,影响内存回收。
ptmalloc,tcmalloc和jemalloc内存分配策略研究相关推荐
- ptmalloc、tcmalloc与jemalloc内存分配器对比分析
目录 背景介绍 ptmalloc 系统向看ptmalloc内存管理 用户向看ptmalloc内存管理 线程中内存管理 Chunk说明 tcmalloc 系统向看tcmalloc内存管理 用户向看tcm ...
- 内存优化总结: ptmalloc、tcmalloc 和 jemalloc
这里填写标题 1. 内存优化总结: ptmalloc.tcmalloc 和 jemalloc 1.1. tcmalloc, jemalloc 和 ptmalloc 对比 1.2. 需求 1.3. 目标 ...
- 内存优化总结:ptmalloc、tcmalloc和jemalloc
概述 需求 系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升. 比如nginx, 它在每个连接accept后会mallo ...
- c++内存管理优化之ptmalloc,tcmalloc,jemalloc使用实例
ptmalloc 是glibc的内存分配管理 tcmalloc 是google的内存分配管理模块 jemalloc 是BSD的提供的内存分配管理 写一段代码测试一下 #include <stdl ...
- mysql tcmalloc jemalloc_tcmalloc jemalloc 和ptmalloc 对比
ptmalloc 是glibc的内存分配管理 tcmalloc 是google的内存分配管理模块 jemalloc 是BSD的提供的内存分配管理 三者的性能对比参考从网上的一个图如下: 自己测试了一下 ...
- 利用TCMalloc替换Nginx和Redis默认glibc库的malloc内存分配
TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员.与标准的glibc库的Malloc相比,TCMalloc库在内存分 ...
- jemalloc内存分配器简介
目录 JeMalloc 基础知识 size_class - jemalloc 分配的内存大小 base - jemalloc 元数据内存的结构 bin - 使用中的 slab集合 extent - ...
- tcmalloc jemalloc glibc内存分配管理模块性能测试对比
tcmalloc是谷歌提供的内存分配管理模块 jemalloc是FreeBSD提供的内存分配管理模块 glibc是Linux提供的内存分配管理模块 并发16个线程,分配压测3次,每次压15分钟,可以看 ...
- ptmalloc内存分配和回收详解(文字版)
ptmalloc内存分配和回收详解(文字版) 进程默认内存布局(x86) 从进程的内存布局可知,.bss段之上的这块分配给用户程序的空间被称之为heap,start_brk指向heap的开始,而brk ...
最新文章
- 程序员的幸福:上个月被裁拿赔偿,这个月找到涨薪50%的工作
- 100法拉电容生猛无线充电背后原因
- Properties作为Map集合的特有方法
- Handling partially written hint files hint file 部分写成功
- 从串行线程封闭到对象池、线程池
- 设计模式——中介者模式
- .NET截取指定长度汉字超出部分以...代替
- (9)Verilog inout使用方法(FPGA不积跬步101)
- 金蝶kiss对计算机软件的要求,金蝶软件的产品适用范围分析
- VC++ 禁止WebBrowser网页跳转时发出的声音和禁止网页上的文字被选择
- 归并排序 Java实现 简单易懂
- GTK+的编译还真麻烦
- linux内网劫持教程,利用kali进行dns劫持入侵局域网
- linux 命令:yum 详解
- WLAN适配器故障(消失)的最快解决办法
- 完美解决Pyqt5 调用软键盘适用于触摸屏
- python获取股票_python根据股票代码获取当前数据
- ElasticSearch---------------------step3,安装Kibana
- 不确定性的人生,其实是有确定性的东西
- 软件工程作业(流程图,盒图)