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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tcmalloc

Tcmalloc Ptmalloc在性能上还是存在一些问题的,比如不同分配区(arena)的内存不能交替使用,比如每个内存块分配都要浪费8字节内存等等,所以一般倾向于使用第三方的malloc。 Tcmalloc是Google gperftools里的组件之一。…

JVM自动内存管理机制——Java内存区域(下)

一、虚拟机参数配置 在上一篇《Java自动内存管理机制——Java内存区域(上)》中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置。 1、Java堆参数设置 a)下面是一些简单的使用参数 其中最后一个是一个运…

PHP版选择排序法

2019独角兽企业重金招聘Python工程师标准>>> <?php// 选择排序法函数function selection_sort(&$array) {$array_length count($array); // 数组的长度$temp 0; // 交换时用到的临时变量for ($i 0; $i < $array_length - 1; $i) {// 认为数组第$i个元…

boost::stable_vector简单解析

由于vector底层实现的机制是一个动态数组&#xff0c;因此使用std::vector<T>时&#xff0c;如果海量数据量时&#xff0c;会导致vector底层的数组很大很大&#xff0c;这样就会导致database很快就会出现内存不足而导致系统停止运行或卡住&#xff0c;这时就要考虑是否用…

理解zookeeper选举机制

转载&#xff1a;https://www.cnblogs.com/shuaiandjun/p/9383655.html 一、zookeeper集群 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的&#xff0c;每个服务器上的数据是相同的&#xff0c;每一个服务器均可以对外提供读和写的服务&#xff0c;这点和red…

使用交互环境

使用交互环境许多脚本语言的解释器都提供了交互环境&#xff0c;我们可通过此环境与计算机沟通交流。为什么叫做交互环境&#xff1f;因为我们在这里通过编程语言与计算机沟通&#xff0c;让它做任何事情&#xff0c;它都会立刻照办并给予我们反馈。运行REBOL 解释器的方式很简…

[原创]K8 cping 3.0大型内网渗透扫描工具

[原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器&#xff1f;其实也是插件化&#xff0c;但Cscan不需要编程同样可实现自定义功能&#xff0c;这比单纯插件化更容易实现插件功能Cscan旨在为用户提供一个高…

std::string的resize()与reserve()的区别

std::string的resize()与reserve()的区别: resize()&#xff1a;改变的是size()与capacity()的大小 (1)、比原来的变小之后&#xff0c;后面的会被截断 (2)、比原来的变大之后&#xff0c;后面的会被填充新的东西&#xff0c;不同的编译器可能会不同 reserve()&#xff1a;…

iMouse - 快速切换鼠标左右键

(此Blog是iMouse软件的官网)【名称】&#xff1a;iMouse【版本】&#xff1a;v1.2 (v1.2是首个公开发布版本&#xff0c;也是最新版&#xff0c;之前版本没有对外发布)【时间】&#xff1a;2012-01-06【关键词】&#xff1a;腱鞘炎、Swap、Mouse、切换、鼠标、鼠标手【功能】&a…

基本排序算法及分析(二):冒泡排序

冒泡排序和改进的冒泡排序 1/**//*------------------------------------------------------------------------------------------- 2Bubble_sort.h 3冒泡排序&#xff1a; 时间复杂度为O(N^2) 4改进的冒泡排序&#xff1a; 时间复杂度仍为O(N^2) 5 一般的冒泡排序方法有可…

洛谷负环板子题

洛谷负环板子题 差点没笑死我 之前的题解都在清一色diss bfs&#xff0c;吹爆dfs 如今改了数据bfs又崛起了&#xff0c;dfs回家种地了&#xff0c;哈哈哈哈哈 dfs版 1 // luogu-judger-enable-o22 #include<iostream>3 #include<cstdio>4 #include<queue>5 #…

std::vector中resize()和reserve()区别

在STL容器中vector用的还是比较多的&#xff0c;但是在使用时&#xff0c;会对resize()和reserve()的使用产生迷惑&#xff0c;现在就对这一情况做个对比&#xff1a; resize()&#xff1a;改变的是size()与capacity()的大小 (1)、比原来的变小之后&#xff0c;后面的会被截断…

设计师和开发人员更快完成工作需求的35个惊人的jquery插件教程(下)

jQuery是一个快速&#xff0c;简洁的工具&#xff0c;它可以遍历HTML文档&#xff0c;处理事件&#xff0c;执行动画&#xff0c;并添加AJAX。jQuery赋予web开发更多的选择机会&#xff0c;使网站产生令人难以置信的元素效果不像之前需要写下几十行代码实现相同的效果&#xff…

函数局部变量和函数的参数在栈中的布局

#include <stdio.h> #include <iostream>using namespace std; void func(int p1, int p2, int p3) {int a p1;int b p2;int c p3;std::cout << "函数参数入栈顺序(栈在内存中向上伸长):从右到左" << std::endl;std::cout << &quo…

经验:Windows To Go准备工作

如果您准备使用USB设备带着您的移动Windows的话&#xff0c;您需要做好准备。从开发预览版到正式版&#xff0c;我也一直关注着Windows Go To这个新功能&#xff0c;所以&#xff0c;总结了些经验&#xff0c;分享给大家&#xff0c;希望能够帮助到大家&#xff0c;或者减少您的…

关于SQLSERVER的全文目录跟全文索引的区别

很久没有写随笔了&#xff0c;本来之前想写一篇关于SQLSERVER全文索引的随笔&#xff0c;可惜没有时间&#xff0c;一直拖到现在才有时间写&#xff0c;不好意思让各位久等了~ 先介绍一下SQLSERVER中的存储类对象&#xff0c;哈哈&#xff0c;先介绍一下概念嘛&#xff0c;让新…

安装rlwrap 的简单方法

1. 下载安装 epel包 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 2. 安装rlwrap yum install rlwrap -y 然后进入oracle 就可以 正常的上下键进行功能切换了 注意需要使用命令 rlwrap sqlplus / as sysdba 转载于:https://www.cnblogs.…

C语言中的内存分配

在任何程序设计环境及语言中&#xff0c;内存管理都十分重要。在目前的计算机系统或嵌入式系统中&#xff0c;内存资源仍然是有限的。因此在程序设计中&#xff0c;有效地管理内存资源是程序员首先考虑的问题。 第1节主要介绍内存管理基本概念&#xff0c;重点介绍C程序中内存的…

强化学习(十七) 基于模型的强化学习与Dyna算法框架

在前面我们讨论了基于价值的强化学习(Value Based RL)和基于策略的强化学习模型(Policy Based RL)&#xff0c;本篇我们讨论最后一种强化学习流派&#xff0c;基于模型的强化学习(Model Based RL)&#xff0c;以及基于模型的强化学习算法框架Dyna。 本篇主要参考了UCL强化学习课…

high-speed A/D performance metrics and Amplifie...

2019独角兽企业重金招聘Python工程师标准>>> High-Speed A/D performance metrics 在高速情况下&#xff0c;主要考虑信号参数的频率范围、失真和噪声。During system definition&#xff0c;setting time 、 acquisition time、static precision-related&#xff0…