Linux内存模型.pdf

  1. 1、本文档共20页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Linux内存模型

1 Linux 内存模型 例如程序代码中定义的函数,地址都在test 段中,而程序中的局部变量都在栈里,对于 小块内存分配,在堆上,而对于大块内存(128K)分配,则由mmap 映射到文件映射区。 Bss 代表未初始化和初始化为 0 的全局变量,bss 类型的全局变量不占用可执行文件的 空间,只在运行时占用内存空间。 Data 中存放初始化为非0 的非常量变量。Data 类型的全局变量是即占文件空间,也占 用运行时内存空间的。 Rodata 存放一些只读数据,这段数据可以在多个进程间共享 Free(NULL) 是合法的,malloc(0)会分配成功,并返回最小内存给你。malloc 分配的内存 是堆内存,由于堆没有自己的机器指令,所以要有系统自己编写算法来管理这片内存,通常 的做法是用链表,在每片被分配的内存前 加个表头,里面存储了被分配内存的起始地址和 大小,你的 malloc 返回的就是表头里的起始指针,这个地址是由一系列的算法得来了,通 常不会为0,一旦分 配成功,就返回一个有效的指针,对于分配 0 空间来说,算法已经算 出可用内存的起始地址,但是你占用0 空间,所以对那个指针操作就是错误的,操作系统一 般不 知道其终止地址,因为有占用大小就可以推出终止地址,还有就是即使分配0 空间也 要释放它,其实是释放的链表结点,返回的指针是可用地址的起始地址,虽然你可以无限赋 值,但是其实是错误的,因为可能有其他有用的数据在那一片区域,如果指针越界就会出现 意想不到的事情. 2 内存管理 空闲的内存结构 这使得无需要额外的内存来管理空闲块,利用空闲块自己,把空闲块强制转换成一个双 向链表就行了。 已经分配出去的内存结构 如果前面有一块有效内存块的,则第一个size_t 指明前一块内存的大小。 第二个size_t 指明自己的大小,同时还指明:自己是不是用mmap 分配的(M),前面是 否有一个效内存块(P)。你可能觉得奇怪,在32 位机上,sizeof(size_t)就是32 位,怎么还 能留下两个位来保存标志呢?前面我们说了,会对内存长度取整,保证最低2 或3bits 为0 , 即是空闲的。 从虚拟内存到物理内存的映射并不是一个字节一个字节映射的,而是以一个称为页 (page)最小单位的为基础的,页的大小视硬件平台而定,通常是4K 。当应用程序访问的内存 所在页面不在物理内存中时,MMU 产生一个缺页中断,并挂起当前进程,缺页中断负责把 相应的数据从磁盘读入内存中,再唤醒挂起的进程。 进程的虚拟内存与物理内存映射关系如下图所示(灰色页为被不在物理内存中的页): 也许我们很少直接使用共享内存,实际上除非性能上有特殊要求,我更愿意采用socket 或 者管道作为进程间通信的方式。但我们常常间接的使用共享内存,大家都知道共享库(或 称为动态库)的优点是,多个应用程序可以公用。如果每个应用程序都加载 一份共享库到 内存中,显然太浪费了。所以操作系统把共享库放在共享内存中,让多个应用程序共享。另 外,同一个应用程序运行多个实例时,也采用同样的方式, 保证内存中只有一份可执行代 码。这样的共享内存是设为只读属性的,防止应用程序无意中破坏它们。当调试器要设置断 点时,相应的页面被拷贝一分,设置为可写 的,再向其中写入断点指令。这些事情完全由 操作系统等底层软件处理了,应用程序本身无需关心。 共享内存是怎么实现的呢?我们来看看下图(黄色页为共享内存): 由上图可见,实现共享内存非常容易,只是把两个进程的虚拟内存映射同一块物理内存 就行了。不过要注意,物理内存相同而虚拟地址却不一定相同,如图中所示进程1 的page5 和进程2 的page2 都映射到物理内存的page1 上。 3 常见内存错误 3.1 内存泄露。 大家都知道,在堆上分配的内存,如果不再使用了,应该把它释放掉,以便后面其它地 方可以重用。在C/C++中,内存管理器不会帮你自动回收不再使用的内存。如果你忘了释放 不再使用的内存,这些内存就不能被重用,就造成了所谓的内存泄露。 把 内存泄露列为首位,倒并不是因为它有多么严重的后果,而因为它是最为常见的一 类错误。一两处内存泄露通常不至于让程序崩溃,也不会出现逻辑上的错误,加上 进程退 出时,系统会自动释放该进程所有相关的内存,所以内存泄露的后果相对来说还是比较温和 的。当然了,量变会产生质变,一旦内存泄露过多以致于耗尽内 存,后续内存分配将会失 败,程序可能因此而崩溃。

文档评论(0)

dajuhyy + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档