Tcmalloc

Tcmalloc

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

Tcmalloc是Google gperftools里的组件之一。全名是 thread cache malloc(线程缓存分配器)其内存管理分为线程内存中央堆两部分。

 

小内存分配

对于小块内存分配,其内部维护了60个不同大小的分配器(实际源码中看到的是86个),和ptmalloc不同的是,它的每个分配器的大小差是不同的,依此按8字节、16字节、32字节等间隔开。在内存分配的时候,会找到最小复合条件的,比如833字节到1024字节的内存分配请求都会分配一个1024大小的内存块。如果这些分配器的剩余内存不够了,会向中央堆申请一些内存,打碎以后填入对应分配器中。同样,如果中央堆也没内存了,就向中央内存分配器申请内存。

在线程缓存内的60个分配器(_文档上说60个,但是我在2.0的代码里看到得是86个_)分别维护了一个大小固定的自由空间链表,直接由这些链表分配内存的时候是不加锁的。但是中央堆是所有线程共享的,在由其分配内存的时候会加自旋锁(spin lock)。

在线程内存池每次从中央堆申请内存的时候,分配多少内存也直接影响分配性能。申请地太少会导致频繁访问中央堆,也就会频繁加锁,而申请地太多会导致内存浪费。在tcmalloc里,这个每次申请的内存量是动态调整的,调整方式使用了类似把tcp窗口反过来用的慢启动(slow start)算法调整max_length, 每次申请内存是申请max_length和每个分配器对应的num_objects_to_move中取小的值的个数的内存块。

num_objects_to_move取值比较简单,是以64K为基准,并且最小不低于2,最大不高于32的值。也就是说,对于大于等于32K的分配器这个值为2(好像没有这样的分配器 class),对于小于2K的分配器,统一为32。其他的会把数据调整到64K / size 的个数。(可能是经验数值,目前2.0版本里的代码是这么写的)

对于max_length就比较复杂了,而且其更多是用于释放内存。max_length由1开始,在其小于num_objects_to_move的时候每次累加1,大于等于的时候累加num_objects_to_move。释放内存的时候,首先max_length会对齐到num_objects_to_move,然后在大于num_objects_to_move的释放次数超过一定阀值,则会按num_objects_to_move缩减大小。

大内存分配

对于大内存分配(大于8个分页, 即32K),tcmalloc直接在中央堆里分配。中央堆的内存管理是以分页为单位的,同样按大小维护了256个空闲空间链表,前255个分别是1个分页、2个分页到255个分页的空闲空间,最后一个是更多分页的小的空间。这里的空间如果不够用,就会直接从系统申请了。

分页管理 – span

Tcmalloc使用一种叫span的东东来管理内存分页,一个span可以包含几个连续分页。一个span的状态只有未分配(这时候在空闲链表中),作为大对象分配,或作为小对象分配(这时候span内记录了小对象的class size)。

在32位系统中,span分为两级由中央分配器管理。第一级有2^5个节点,第二级是2^15个。32位总共只能有2^20个分页(每个分页4KB = 2^12)。(骗纸,我在代码里明明看到的是2^7和2^13,定义了TCMALLOC_LARGE_PAGES宏之后才是 2^5和2^15,可是所有的代码或者编辑脚本里都没定义这个宏,可能是文档没更新)

在64为系统中,有三级。

资源释放的时候,首先计算其分页编号,然后再查找出它对应的span,如果它是一个小对象,则直接归入小对象分配器的空闲链表。等到空闲空间足够大以后划入中央堆。如果是大对象,则会把物理地址连续的前后的span也找出来,如果空闲则合并,并归入中央堆中。

而线程缓存内的分配器,会根据max_length、num_objects_to_move和上一次垃圾收集到现在为止的最小链表长度,按一定的策略回收资源到中央堆中,具体的算法不再复述tcmalloc的文档写得比较清楚。同样可以在需要时减少某一个线程的max_length来转移内存,但是要等到那个线程下一次执行free,触发垃圾回收之后才会真正把内存返还中央堆。

简而言之,就是:

**小内存: 线程缓存队列 -> 中央堆 -> 中央页分配器(从系统分配)

大内存: 中央堆 -> 向系统请求

Tcmalloc的管理策略和ptmalloc有很大区别,理论上性能提高的主要原因在线程缓存不加锁和少量操作的自旋锁上。不过按照它的实现方式,不适合多线程频繁分配大于8个分页(32KB)的内存。否则自旋锁争用会相当厉害,不过这种情况也比较少。而减少和中央堆交互又依赖于他的线程缓存长度自适应算法。

还有就是它使用了外部的数据结构来管理span list,这样不会每次分配内存都要浪费header的长度。但是他的对齐操作又比ptmalloc多浪费了一些内存。(有点空间换时间的意思)

所以无论是ptmalloc还是tcmalloc都应该尽量减少大内存的分配和释放。尽量先分配、后释放。

 

ptmalloc与tcmalloc的不足:

    都是针对小内存分配和管理;对大块内存还是直接用了系统调用。应该尽量避免大内存的malloc/new、free/delete操作。频繁分配小内存,例如:对bool、int、short进行new的时候,造成内存浪费。

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

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

相关文章

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…

WebCombo

原文来自方案网 http://www.fanganwang.com/Product-detail-item-1162.html&#xff0c;欢迎转载。 关键字&#xff1a; WebCombo.NET 是一款基于AJAX技术&#xff0c;处于行业领先地位的Combo box控件。它提供众多高级的数据输入功能及其独特的技术。通过其内置的数据过滤功能…