当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 
1、检查要访问的虚拟地址是否合法 
2、查找/分配一个物理页 
3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 
4、
建立映射关系(虚拟地址到物理地址) 
重新执行发生缺页中断的那条指令 
如果第3步,需要读取磁盘,那么这次缺页中断就是majflt,否则就是minflt。 

内存分配的原理

从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。

1、brk是将数据段(.data)的最高地址指针_edata往高地址推;

2、mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存

     这两种方式分配的都是虚拟内存,没有分配物理内存在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。


在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk,mmap,munmap这些系统调用实现的。

下面以一个例子来说明内存分配的原理:

情况一、malloc小于128k的内存,使用brk分配内存,将_edata往高地址推(只分配虚拟空间,不对应物理内存(因此没有初始化),第一次读/写数据时,引起内核缺页中断,内核才分配对应的物理内存,然后虚拟地址空间建立映射关系),如下图:


1、进程启动的时候,其(虚拟)内存空间的初始布局如图1所示。
      其中,mmap内存映射文件是在堆和栈的中间(例如libc-2.2.93.so,其它数据文件等),为了简单起见,省略了内存映射文件。
      _edata指针(glibc里面定义)指向数据段的最高地址。 
2、
进程调用A=malloc(30K)以后,内存空间如图2:
      malloc函数会调用brk系统调用,将_edata指针往高地址推30K,就完成虚拟内存分配。
      你可能会问:只要把_edata+30K就完成内存分配了?
      事实是这样的,_edata+30K只是完成虚拟地址的分配,A这块内存现在还是没有物理页与之对应的,等到进程第一次读写A这块内存的时候,发生缺页中断,这个时候,内核才分配A这块内存对应的物理页。也就是说,如果用malloc分配了A这块内容,然后从来不访问它,那么,A对应的物理页是不会被分配的。 
3、
进程调用B=malloc(40K)以后,内存空间如图3。

情况二、malloc大于128k的内存,使用mmap分配内存,在堆和栈之间找一块空闲内存分配(对应独立内存,而且初始化为0),如下图:

4、进程调用C=malloc(200K)以后,内存空间如图4:
      默认情况下,malloc函数分配内存,如果请求内存大于128K(可由M_MMAP_THRESHOLD选项调节),那就不是去推_edata指针了,而是利用mmap系统调用,从堆和栈的中间分配一块虚拟内存。
      这样子做主要是因为::
      brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的,这就是内存碎片产生的原因,什么时候紧缩看下面),而mmap分配的内存可以单独释放。
      当然,还有其它的好处,也有坏处,再具体下去,有兴趣的同学可以去看glibc里面malloc的代码了。 
5、进程调用D=malloc(100K)以后,内存空间如图5;
6、进程调用free(C)以后,C对应的虚拟内存和物理内存一起释放。

7、进程调用free(B)以后,如图7所示:
        B对应的虚拟内存和物理内存都没有释放,因为只有一个_edata指针,如果往回推,那么D这块内存怎么办呢
当然,B这块内存,是可以重用的,如果这个时候再来一个40K的请求,那么malloc很可能就把B这块内存返回回去了。 
8、进程调用free(D)以后,如图8所示:
        B和D连接起来,变成一块140K的空闲内存。
9、默认情况下:
       当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)。在上一个步骤free的时候,发现最高地址空闲内存超过128K,于是内存紧缩,变成图9所示。

malloc原理和内存碎片的更多相关文章

  1. malloc原理和内存碎片[转]

    当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 4.建立映射关系 ...

  2. malloc原理和内存碎片【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3820852.html 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查 ...

  3. 虚拟空间,malloc

    一,内存空间分布图 所以,mmap其实和堆一样,实际上可以说他们都是动态内存分配,但是严格来说mmap区域并不属于堆区,反而和堆区会争用虚拟地址空间. 这里要提到一个很重要的概念,内存的延迟分配,只有 ...

  4. Linux 进程地址空间及原理

    1.程序地址空间      首先,我们先看学c/c++时候学到的程序内存布局: 准确地说,程序地址空间其实就是进程的地址空间,实际就是pcb中的mm_struct. 接下来,我们用fork()演示一下 ...

  5. 面试准备——(二)专业知识(2)Python

    面试遇到的问题: 滴滴: 1. Python的数据结构 2. list和tuple的区别 3. list中有哪些操作?append和extend的区别? 4. list和dict的却别?dict是有序 ...

  6. C语言中的内存分配与释放

    C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...

  7. iOS开发——C篇&动态内存分配

    再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数 再 ...

  8. iOS开发——C篇&动态内存分析

    再C语言中关于内存是一个很重要的知识点,所以今天我就从c语言的内存分配开始为大家解析一下C语言再iOS开发中非常重要的一些知识. 1:malloc函数的介绍 C语言中开辟内存空间:malloc函数(堆 ...

  9. flv文件解析(纯c解析代码)

    参考链接: 1. FLV科普12 FLV脚本数据解析-Metadata Tag解析 https://blog.csdn.net/cabbage2008/article/details/50500021 ...

随机推荐

  1. vtk第一个程序

    首先 设置环境变量 解决方案资源管理器 选中项目名字 而不是ALL_BUILD 选项卡 项目-属性 右侧 附加依赖项->编辑 kernel32.libuser32.libgdi32.libwin ...

  2. 删除某一BSC在某一时间段内的数据

    DELETE FROM cdl_raw_do_12501_ztev8_sht_201509 WHERE call_start_time >= STR_TO_DATE( '2015-09-14 2 ...

  3. HTML5 video 视频标签 常用属性

    最近在做手机端的 h5 页面的视频直播功能,用到了 Video 标签.其常用的属性有以下几个: src.poster.preload.autoplay.loop.controls.width.heig ...

  4. Javascript高级程序设计——在HTML中使用Javascript

    <script>元素 向HTML页面中插入Javascript的主要方法,就是使用<script>元素,<script>元素有六个属性: async:可选.表示应该 ...

  5. iOS开发初级课程

    iOS开发初级课程 针对学员 掌握Objective  C,C或者C++,有语言基础的学员,想从事iOS开发工作. iOS开发那些事-了解iOS开发(8集) 在课程中,我们首先介绍如何使用nib和故事 ...

  6. 160809209_李梦鑫_C语言程序设计实验2 选择结构程序设计

    实验2-1 输入3个数,并按由大到小的顺序输出. 实验要求: 编写一个C程序,输入3个数,并按由大到小的顺序输出. 源码:#include <stdio.h> int main() { i ...

  7. php preg_库正则匹配

    <?php //preg_库提供的正则 preg_match();//进行正则表达式匹配 /* preg_match (pattern , subject, matches) 参数 描述 pat ...

  8. qmake的使用

    [TOC] 本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso 本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso *** 还是先说 ...

  9. ASIO插件 真的能提升 音质?(听音乐者必看)

    最近在倒弄HIFI音乐播放器footbar2000的配置时,发现了2011年的一个神贴, 最牛逼的是,这个神贴到现在还屹立不倒,还有很多无知的人在下面膜拜, 我真的想问:你这么优秀,都能逆天反转音质, ...

  10. 解决ckeditor中文路径无法下载,无法显示图片问题

    使用ckfinder上传的文件如果是中文路径,下载的时候会找不到 假如使用tomcat服务器,找到tomcat目录>conf文件夹的server.xml>用查找找到Connector这个 ...