内存管理可以分为三个层次,自底向上分别是:

  • 操作系统内核的内存管理
  • 用户空间lib库的内存管理算法
  • 应用程序从lib库申请内存后,根据应用程序本身的程序特性进行优化, 比如使用引用计数std::shared_ptr,内存池方式等等。

1. 用户空间内存管理

目前大部分用户控件程序使用glibc提供的malloc/free系列函数,而glibc使用的ptmalloc2在性能上远远弱后于google的tcmalloc和facebook的jemalloc。 而且后两者只需要使用LD_PRELOAD环境变量启动程序即可,甚至并不需要重新编译。

1.1 ptmalloc2

malloc是一个C库中的函数,malloc向glibc请求内存空间。glibc初始分配或者通过brk和sbrk或者mmap向内核批发内存,然后“卖”给我们malloc使用。

既然brk、mmap提供了内存分配的功能,直接使用brk、mmap进行内存管理不是更简单吗,为什么需要glibc呢?

因为系统调用,导致程序从用户态陷入内核态,比较消耗资源。为了减少系统调用带来的性能损耗,glibc采用了内存池的设计,增加了一个代理层,每次内存分配,都优先从内存池中寻找,如果内存池中无法提供,再向操作系统申请。

1.2 tcmalloc

tcmalloc 是google开发的内存分配算法库,用来替代传统的malloc内存分配函数,它有减少内存碎片,适用于多核,更好的并行性支持等特性。

要使用tcmalloc,只要将tcmalloc通过-ltcmalloc连接到应用程序即可。
也可以使用LD_PRELOAD在不是你自己编译的应用程序中使用:$ LD_PRELOAD="/usr/lib/libtcmalloc.so"

2. 内核空间内存管理

linux操作系统内核,将内存分为一个个页去管理。

2.1 页面管理算法–伙伴系统

在实际应用中,而频繁地申请和释放不同大小的连续页框,必然导致在已分配页框的内存块中分散了许多小块的空闲页框。这样,即使这些页框是空闲的,其他需要分配连续页框的应用也很难得到满足。

为了避免出现这种内存碎片,Linux内核中引入了伙伴系统算法(buddy system)。

2.1.1 Buddy(伙伴的定义)

满足以下三个条件的称为伙伴:
1)两个块大小相同;
2)两个块地址连续;
3)两个块必须是同一个大块中分离出来的;

2.1.2 Buddy算法的分配

假设要申请一个256个页框的块,先从256个页框的链表中查找空闲块,如果没有,就去512个页框的链表中找,找到了则将页框块分为2个256个页框的块,一个分配给应用,另外一个移到256个页框的链表中。如果512个页框的链表中仍没有空闲块,继续向1024个页框的链表查找,如果仍然没有,则返回错误。

2.1.3 Buddy算法的释放

内存的释放是分配的逆过程,也可以看作是伙伴的合并过程。页框块在释放时,会主动将两个连续的页框块合并为一个较大的页框块。

2.2 Slab机制

slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象,如进程描述符等,这些对象的大小一般比较小,如果直接采用伙伴系统来进行分配和释放,不仅会造成大量的内碎片,而且处理速度也太慢。

而slab分配器是基于对象进行管理的,相同类型的对象归为一类(如进程描述符就是一类),每当要申请这样一个对象,slab分配器就从一个slab列表中分配一个这样大小的单元出去,而当要释放时,将其重新保存在该列表中,而不是直接返回给伙伴系统,从而避免这些内碎片。slab分配器并不丢弃已分配的对象,而是释放并把它们保存在内存中。当以后又要请求新的对象时,就可以从内存直接获取而不用重复初始化。

2.3 内核中申请内存的函数

2.3.1 __get_free_pages

__get_free_pages函数是最原始的内存分配方式,直接从伙伴系统中获取原始页框,返回值为第一个页框的起始地址.

2.3.2 kmem_cache_alloc

kmem_cache_create/ kmem_cache_alloc是基于slab分配器的一种内存分配方式,适用于反复分配释放同一大小内存块的场合。首先用kmem_cache_create创建一个高速缓存区域,然后用kmem_cache_alloc从 该高速缓存区域中获取新的内存块。

2.3.3 kmalloc

kmalloc是内核中最常用的一种内存分配方式,它通过调用kmem_cache_alloc函数来实现。

kmalloc() 申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因为存在较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。
较常用的flags()有:

GFP_ATOMIC —— 不能睡眠;
GFP_KERNEL —— 可以睡眠;
GFP_DMA —— 给 DMA 控制器分配内存,需要使用该标志。

2.3.4 vmalloc

vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。

注意vmalloc和vfree时可以睡眠的,因此不能从中断上下问调用。

一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。例如,当模块被动态加载到内核当中时,就把模块装载到由 vmalloc() 分配的内存上。

linux内存管理总结相关推荐

  1. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

  2. 万字长文,别再说你不懂Linux内存管理了(合辑),30 张图给你安排的明明白白...

    之前写了两篇详细分析 Linux 内存管理的文章,读者好评如潮.但由于是分开两篇来写,而这两篇内容其实是有很强关联的,有读者反馈没有看到另一篇读起来不够不连贯,为方便阅读这次特意把两篇整合在一起,看这 ...

  3. 别再说你不懂Linux内存管理了,10张图给你安排的明明白白!

    来自:后端技术学堂 过去的一周有点魔幻,有印象的有三个新闻:天猫总裁绯闻事件,蘑菇街裁员,不可能打工的周某也放出来了.三件事,两件和互联网行业相关,好像外面的世界很是精彩啊!吃瓜归吃瓜,学习还是不能落 ...

  4. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  5. Linux内存管理【转】

    转自:http://www.cnblogs.com/wuchanming/p/4360264.html 转载:http://www.kerneltravel.net/journal/v/mem.htm ...

  6. Linux内存管理之高端内存映射

    一:引子 我们在前面分析过,在linux内存管理中,内核使用3G->4G的地址空间,总共1G的大小.而且有一部份用来做非连续空间的物理映射(vmalloc).除掉这部份空间之外,只留下896M大 ...

  7. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  8. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  9. Linux内存管理 (4)分配物理页面

    专题:Linux内存管理专题 关键词:分配掩码.伙伴系统.水位(watermark).空闲伙伴块合并. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行. 从Linux内存 ...

  10. Linux 交换内存空间原理(swap)(Linux内存管理)(cgroups)

    文章目录 什么是swap? 为什么需要swap? swap的缺点? 到底要不要swap? 内存不够用 内存勉强够用 内存充裕 桌面环境 服务器环境 swap大小配置多少比较合适? 怎么配置swap? ...

最新文章

  1. oracle 数据库里查看表空间使用状况
  2. VS新建工程或者新建项时 出现未定义标识符号
  3. python线性回归模型预处理_线性回归-2 数据预处理与模型验证评估
  4. centos 桥接配置 设置网络代理 lnmp搭建
  5. python return函数_理解Python函数中的return关键字
  6. 标注工具——yarn的学习笔记
  7. bundler for jekyll
  8. 不固定宽度的div居中显示
  9. iOS安装CocoaPods详细过程
  10. nmon和nmon analyser使用方法
  11. 直播系统开发需要注意的事项
  12. DIY专门制作PCB的雕刻机--所需软件
  13. QGIS无人机数据分析教程
  14. javascript继承的6种方法
  15. 搜索引擎下拉食云速捷详细_搜索框下拉优化淹云速捷讲信誉,下拉词上词77云26速26捷...
  16. 从零搭建vue-ssr详细介绍
  17. 邮政网络与计算机网络的区别,邮政储蓄计算机网络系统分析与评价
  18. 耿丹CS16-2班第七次作业汇总
  19. TCP-IP详解:SACK选项(wireshark抓包有SLE和SRE的SACK包)
  20. r ridge回归_手把手带你画高大上的lasso回归模型图

热门文章

  1. java eden分配参数,JVM垃圾收集器与内存分配策略,
  2. 北邮 鲁鹏老师 视频笔记
  3. heatmap(热图)
  4. flatform installer web 安装php_安装PHP扩展
  5. php 中间表统计,多对多中间表详解
  6. java中字符 的含义 有什么作用_Java中字符串常见题之String相关讲解
  7. python同时读取多个文件的同一行
  8. 计算机管理在哪个里面,在计算机中哪个子系统是其他子系统的管理者
  9. python中的记录指针_使用Python向C语言的链接库传递数组、结构体、指针类型的数据...
  10. maven 集成 CXF