转载: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的内存分配使用有几个注意事项

  1. Ptmalloc默认后分配内存先释放,因为内存回收是从top chunk开始的。
  2. 避免多线程频繁分配和释放内存,会造成频繁加解锁。
  3. 不要分配长生命周期的内存块,容易造成内碎片,影响内存回收。

ptmalloc,tcmalloc和jemalloc内存分配策略研究相关推荐

  1. ptmalloc、tcmalloc与jemalloc内存分配器对比分析

    目录 背景介绍 ptmalloc 系统向看ptmalloc内存管理 用户向看ptmalloc内存管理 线程中内存管理 Chunk说明 tcmalloc 系统向看tcmalloc内存管理 用户向看tcm ...

  2. 内存优化总结: ptmalloc、tcmalloc 和 jemalloc

    这里填写标题 1. 内存优化总结: ptmalloc.tcmalloc 和 jemalloc 1.1. tcmalloc, jemalloc 和 ptmalloc 对比 1.2. 需求 1.3. 目标 ...

  3. 内存优化总结:ptmalloc、tcmalloc和jemalloc

    概述 需求 系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升. 比如nginx, 它在每个连接accept后会mallo ...

  4. c++内存管理优化之ptmalloc,tcmalloc,jemalloc使用实例

    ptmalloc 是glibc的内存分配管理 tcmalloc 是google的内存分配管理模块 jemalloc 是BSD的提供的内存分配管理 写一段代码测试一下 #include <stdl ...

  5. mysql tcmalloc jemalloc_tcmalloc jemalloc 和ptmalloc 对比

    ptmalloc 是glibc的内存分配管理 tcmalloc 是google的内存分配管理模块 jemalloc 是BSD的提供的内存分配管理 三者的性能对比参考从网上的一个图如下: 自己测试了一下 ...

  6. 利用TCMalloc替换Nginx和Redis默认glibc库的malloc内存分配

    TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员.与标准的glibc库的Malloc相比,TCMalloc库在内存分 ...

  7. jemalloc内存分配器简介

    目录 JeMalloc 基础知识 size_class -  jemalloc 分配的内存大小 base -  jemalloc 元数据内存的结构 bin - 使用中的 slab集合 extent - ...

  8. tcmalloc jemalloc glibc内存分配管理模块性能测试对比

    tcmalloc是谷歌提供的内存分配管理模块 jemalloc是FreeBSD提供的内存分配管理模块 glibc是Linux提供的内存分配管理模块 并发16个线程,分配压测3次,每次压15分钟,可以看 ...

  9. ptmalloc内存分配和回收详解(文字版)

    ptmalloc内存分配和回收详解(文字版) 进程默认内存布局(x86) 从进程的内存布局可知,.bss段之上的这块分配给用户程序的空间被称之为heap,start_brk指向heap的开始,而brk ...

最新文章

  1. 程序员的幸福:上个月被裁拿赔偿,这个月找到涨薪50%的工作
  2. 100法拉电容生猛无线充电背后原因
  3. Properties作为Map集合的特有方法
  4. Handling partially written hint files hint file 部分写成功
  5. 从串行线程封闭到对象池、线程池
  6. 设计模式——中介者模式
  7. .NET截取指定长度汉字超出部分以...代替
  8. (9)Verilog inout使用方法(FPGA不积跬步101)
  9. 金蝶kiss对计算机软件的要求,金蝶软件的产品适用范围分析
  10. VC++ 禁止WebBrowser网页跳转时发出的声音和禁止网页上的文字被选择
  11. 归并排序 Java实现 简单易懂
  12. GTK+的编译还真麻烦
  13. linux内网劫持教程,利用kali进行dns劫持入侵局域网
  14. linux 命令:yum 详解
  15. WLAN适配器故障(消失)的最快解决办法
  16. 完美解决Pyqt5 调用软键盘适用于触摸屏
  17. python获取股票_python根据股票代码获取当前数据
  18. ElasticSearch---------------------step3,安装Kibana
  19. 不确定性的人生,其实是有确定性的东西
  20. 软件工程作业(流程图,盒图)

热门文章

  1. [JMX一步步来] 9、基于JBoss来写MBean
  2. Linux 高可用(HA)集群之keepalived
  3. 〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
  4. 面向对象编程从骨子里就有问题——看看名人大家是如何吐槽面向对象的
  5. NoSuchElementException
  6. 前端之 XMLHttpRequest
  7. Python3生成脚本实现重置键盘键位
  8. Python02期预科课程笔记索引
  9. 基于FPGA 的8b10b编解码电路前端电路设计
  10. html 圆环实现多种颜色,SVG实现多彩圆环倒计时效果的示例代码