tcmalloc的内存管理
这是一个通用的内存管理库,可以代替new delete之类。内存管理主要关注两点,一是分配、释放的速度,二是内存的利用率,也就是内存碎片问题。这两个目标是冲突的,不同的内存管理算法在两者之间取不同的平衡点
为了提高分配、释放的速度,多核计算机上,主要做的工作是避免所有核同时在竞争内存,常用的做法是内存池,简单来说就是批量申请内存,然后切割成各种长度,各种长度都有一个拉链,申请、释放都只要在链表上操作,可以认为是O(1)的。
不可能所有的长度都对应一个链表。很多内存池是假设,A释放掉一块内存后,B会申请类似大小的内存,但是A释放的内存跟B需要的内存不一定完全相等,可能有一个小的误差,如果严格按大小分配,会导致复用率很低,这样各个拉链上都会有很多释放了,但是没有复用的内存,导致利用率很低。这个问题也是可以解决的,可以回收这些空闲的内存,但是这样就变成传统的内存管理,不停地对内存块作切割和合并,会导致效率低下。所以通常的做法是只分配有限种类的长度。一般的内存池只提供几十种选择。tcmalloc在这点做得比较激进,对于小内存,按8的整数次倍分配,对于大内存,按4K的整数次倍分配。这样做有两个好处,一是分配的时候比较快,那种提供几十种选择的内存池,往往要遍历一遍各种长度,才能选出合适的种类,而tcmalloc则可以简单地做几个运算就行了。二是短期的收益比较大,分配的小内存至多浪费7个字节,大内存则4K。但是长远来说,tcmalloc分配的种类还是比别的内存池要多很多的,可能会导致复用率很低。
所以tcmalloc还要有一套高效的机制回收这些空闲的内存。当一个线程的空闲内存比较多的时候,会交还给进程,进程可以把它调配给其他线程使用;如果某种长度交还给进程后,其他线程并没有需求,进程则把这些长度合并成内存页,然后切割成其他长度。如果进程占据的资源比较多呢,据说不会交回给操作系统。
相当于常见的内存池,tcmalloc的优势体现在:
(1)分配内存页的时候,直接跟OS打交道,而常用的内存池一般是基于别的内存管理器上分配,如果完全一样的内存管理策略,明显tcmalloc在性能及内存利用率上要省掉第三方内存管理的开销。之所以会出现这种情况,是因为大部分写内存池的coder都不太了解OS
(2)大部分的内存池只负责分配,不管回收。当然了,没有回收策略,也有别的方法解决问题。比如线程之间协调资源,模索模块一般是一写多读,也就是只有一个线程申请、释放内存,就不存在线程之间协调资源;为了避免某些块大量空闲,常用的做法是减少内存块的种类,提高复用率,这可能会造成内部碎片比较多,如果空闲的内存实在太多了,还可以直接重启。
作为一个通用的内存管理库,tcmalloc也未必能超过专用的比较粗糙的内存池。比如应用中主要用到7种长度的块,专用的内存池,可以只分配这7种长度,使得没有内部碎片。或者利用统计信息设置内存池的长度,也可以使得内部碎片比较少,以前做过一个工作是统计一下历史上的需求,然后用动态规则去算内存池长度设置,可以使得内部碎片很少,长度分布发生改变,则重启。
所以tcmalloc的意义在于,不需要增加任何开发代价,就能使得内存的开销比较少,而且可以从理论上证明,最优的分配不会比tcmalloc的分配好很多。
对比glibc可以发现,两者的思想其实是差不多的,差别只是在细节上,细节上的差别,对工程项目来说也是很重要的,至少在性能与内存使用率上tcmalloc是领先很多的。glibc在内存回收方面做得不太好,常见的一个问题,申请很多内存,然后又释放,只是有一小块没释放,这时候glibc就必须要等待这一小块也释放了,也把整个大块释放,极端情况下,可能会造成几G的浪费
代码风格方面,tcmalloc是用c风格写的,个人比较喜欢这种风格。不像有些人,喜欢摆弄C++的语法,先声明一个虚基类,然后反复继承实例化之类,一点小功能写个几百上千行,看得云里雾里。当然tcmalloc的代码也很长,我还没读完
建议继续学习:
- Linux内存点滴 用户进程内存空间 (阅读:11598)
- ps - 按进程消耗内存多少排序 (阅读:11356)
- Linux Used内存到底哪里去了? (阅读:10021)
- Linux操作系统的内存使用方法详细解析 (阅读:8921)
- linux内核研究笔记(一)内存管理 – page介绍 (阅读:8766)
- 几个内存相关面试题(c/c++) (阅读:8073)
- 内存越界的概念和调试方法 (阅读:6342)
- Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读:6202)
- 必看!linux系统如何查看内存使用情况 (阅读:6203)
- 让Redis使用TCMalloc,实现高性能NOSql服务器 (阅读:6115)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:杨镇锋 来源: 我思故我在
- 标签: tcmalloc 内存
- 发布时间:2011-01-18 22:05:11
- [69] Twitter/微博客的学习摘要
- [67] IOS安全–浅谈关于IOS加固的几种方法
- [65] 如何拿下简短的域名
- [65] android 开发入门
- [63] find命令的一点注意事项
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [60] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则