【Linux】malloc和free底层的简单实现!!!

9人阅读 评论(0) 收藏 举报
分类:

从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brkmmap(当然在这里是不考虑共享内存)

  1. brk是将数据段(.data)的最高地址指针_edata往高地址推;
  2. mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。
    注:

  3. 在开辟空间的时候只是在进程的虚拟地址空间内开辟指定大小的内存,但是并没有实际在物理内存上面开辟空间,只有当对开辟的内存空间进行访问的时候才会在物理内存上面开辟实际的空间。例如:假如开辟的空间一直没有使用,那么在物理内存上面始终没有实际的空间。

  4. 在这之间当对开辟的内存进行第一次访问的时候会发生缺页中断,这时候系统就会在指定的空间进行开辟内存,然后再将物理内存的地址映射到虚拟地址上面。

    当发生缺页中断的时候系统会干什么?
    1、检查要访问的虚拟地址是否合法
    2、查找/分配一个物理页
    3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干)
    4、建立映射关系(虚拟地址到物理地址)

情况1:

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

在开辟较小的空间的时候会直接将_edata寄存器的指向向髙地址一定指定大小的位置,然后将这个区域映射到虚拟内存地址空间内。但是这时候这个位置并没有实际的物理内存,只有当使用到这块内存的时候才会在物理内存上面开辟空间。

情况2:
当开辟的空间大小大于128K的时候并不是使用brk系统来移动_edata指向来开辟空间,而是使用mmap系统在堆栈之间的共享区直接开辟指定大小的空间(虚拟空间)。
这里写图片描述

同样,在开辟空间之后并没有实际的物理内存空间,当使用的时候才会初始化。

free

当需要销毁的时候,使用mmap开辟的空间会直接释放,如果在物理内存上面开辟的有实际的内存的话也会一起释放。当时使用brk开辟的内存只能依次释放,比如:释放b的时候可以直接释放虚拟内存和物理内存,但是在释放a的时候如果在a的上面还有开辟的空间,那么a这块空间并不会被释放,因为在a的上面还有开辟的空间,但是a这块空间是可以复用的,那么如果在下次开辟空间的时候又开辟了和啊大小的空间,那么很有可能系统就会直接将a这块空间映射到虚拟空间内。
因为使用brk开辟的内存必须等髙地址的内存释放之后才会释放,这也是内存碎片产生的原因。

释放a:
这里写图片描述

释放b:
这里写图片描述

当c也释放的时候,那么_edata指向就会重新回退到含有开辟空间的位置上面。
这里写图片描述

查看评论

下一代的B/S开发框架--Echo 教程(7)

下一代的B/S开发框架--Echo 教程(7) 编写自己的控件羡慕EchoPoint的控件吗? 别担心, 你一样可以做. 写控件可以分两种方法: 搭积木和造积木.A: 搭积木在教程(5)中, 我们实现...
  • steeven
  • steeven
  • 2003-03-19 09:12:00
  • 1512

malloc底层实现

很早之前看了malloc的底层实现,很多同学在面试的时候也会问道,最近整理出来进行,方便大家查看和了解,部分内容摘自他人博客。 其实总的来说,malloc早不同的系统上还有微小的区别,实质mallo...
  • maybe3is3u5
  • maybe3is3u5
  • 2016-07-21 17:12:05
  • 1832

linux下malloc()和free()的原理及实现

在学习C语言的时候知道了动态内存分配的概念,也知道了malloc()的使用方式,但是一直没有去了解或者认真学习malloc()的实现原理。今天看到关于动态内存分配方面的资料,就整理总结下。在C语言中只...
  • c1s2p3
  • c1s2p3
  • 2016-01-15 10:41:34
  • 3197

linux-malloc底层实现原理

本文大致讲解一下linux下malloc的底层实现原理。 首先malloc肯定是从堆中分配内存,而堆又在用户空间中占据什么位置?通过下面这张图可以看出来: 很明显是32位系统,寻址空间是4G,li...
  • mmshixing
  • mmshixing
  • 2016-06-15 13:58:37
  • 6147

从底层的角度看一下malloc和free的细节

事实上,仔细看一下free()的函数原型,也许也会发现似乎很神奇,free()函数非常简单,只有一个参数,只要把指向申请空间的指针传递给free()中的参数就可以完成释放工作!这里要追踪到malloc...
  • eroswang
  • eroswang
  • 2009-06-12 22:29:00
  • 3590

malloc函数详解之自己用C语言写出实现malloc()和free()功能的函数

传送:基于Keil C 编写的更加简洁的版本(空间复杂度比较低)--------------------------------------------------------------------...
  • wxx258369
  • wxx258369
  • 2017-12-06 17:43:28
  • 270

C malloc free 函数实现

让我们编写一个malloc函数,看看它在既有程序中如何工作! 本教程假定你了解指针,知道C语言中 *ptr 间接引用一个指针, ptr->foo 表示 (*ptr).foo,malloc用于内存...
  • u011680118
  • u011680118
  • 2015-10-27 22:34:09
  • 356

linux C 之动态内存分配malloc ,calloc,realloc,free

malloc,free,calloc,realloc -- allocate and free dynamic memory  分配和释放动态内存. 所在包...
  • lcstrive
  • lcstrive
  • 2014-05-09 16:36:43
  • 1663

linux中内存泄漏的检测(二)定制化的malloc/free

《linux中内存泄漏的检测(一)最简单的方法》介绍了最简单的内存泄漏检测方法,这种方法虽然简单,却有很多现实的问题,导致它不能用于实际的生产中。直接使用这种方法肯定是不现实的,因为:(1)把整个工程...
  • mishifangxiangdefeng
  • mishifangxiangdefeng
  • 2016-01-21 09:13:46
  • 2771

malloc/free内存碎片的产生原因

malloc和free大量使用后回造成内存碎片,那么这种碎片形成的机理是什么?如果机理是申请的内存空间大小(太小)所形成的,那么申请多大的区域能够最大限度的避免内存碎片呢(这里的避免不是绝对的避免,只...
  • u012590688
  • u012590688
  • 2015-09-28 20:39:47
  • 1829
    个人资料
    持之以恒
    等级:
    访问量: 9987
    积分: 880
    排名: 5万+
    文章分类