博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转载】malloc内存分配与free内存释放的原理
阅读量:6637 次
发布时间:2019-06-25

本文共 1045 字,大约阅读时间需要 3 分钟。

原文:http://www.cnblogs.com/huhuuu/p/3456662.html

前段时间一直想看malloc的原理,在搜了好几篇malloc源码后遂放弃,晦涩难懂。

  后来室友买了本深入理解计算机系统的书,原来上面有讲malloc的原理,遂看了,先明白理论,在看代码就理解比较快了= =

  1.问题的引入:

   为什么要使用malloc,主要是因为在代码中,为了节约内存,很多数据都是动态生成的,所以会用malloc,对应于C++中的new,底层还是调用malloc.

  2.碎片的问题:

   会有内部碎片与外部碎片的问题,内部碎片难以消除(因为字对齐之类的问题),而外部碎片是可以消除的(如果不消除的话,外部的内存块越来越小,虽然数量多了,但是利用率会急剧下降!)

  3.需要解决的问题:

  

  4.隐式的空闲链表:

  一个简单的堆块,这里只有头部,下面为了优化,还会使用尾部。

  

  隐式的空闲链表:

  

  这样就把用链表的方法把堆空间给联系起来了。特点明显,实现简单,但分配时查询空堆块是线性时间的。

  5.放置以分配的块:

    1)、首次适配:从链表开始寻找适合的空堆块,直到找到为止

    2)、下一次适配:从上一次的分配点开始找,直到找到适合的空堆块为止

    3)、最佳适配:查询整个链表,找到最合适(浪费最小)的空堆块

  6.分割空闲块:

    当前的分配的空堆块比所需要的空间大很多的时候,如果不分割,就会照成内部碎片过大,利用率下降。

    当需要3个字节的空间时,首次适配找到了满足条件的第二个堆块,但堆块过大,所以分割成两个16字节的堆块。

    

  7.获取额外的堆存储器:

   当链表中不能满足申请要求的堆块空间的时候,1)通过合并相邻的堆块空间,形成单个尽量大的堆块空间 2)实在没有其他办法了,分配器通过sbrk函数向内核申请格外的堆空间,分配器将堆空间插入到链表中,然后提供给申请空间的块。

  8.合并

  

  如果,在如上的情况下,合并两个块,由于当前块不知道上一个块的情况,它要通过遍历整个链表才能知道上一个堆块的空间是否为空,这样将花费线性的时间来合并与当前相邻的空闲堆块。有个类似双向链表的方法(不过不是真正的双向链表,只是可以加一个信息量,直接就可以知道上一个堆块的情况)

  

  上一个堆块的情况就容易知道了,下面有四种情况:

  

  

  这样,堆块合并的问题就解决了。

你可能感兴趣的文章
关于新版本cuckoo hook位置变动的思考
查看>>
PHP入门【1】
查看>>
FastCgi与PHP-fpm之间是个什么样的关系
查看>>
Servlet 代码模板
查看>>
Dell 服务器报错Voltage sensor detected a failure value
查看>>
jquery判断某个属性是否存在 hasAttr
查看>>
实战体验-天津ITAA实验室-每周末
查看>>
redis群集节点删除和添加
查看>>
Quartz Core 图层编程
查看>>
一课OO设计模式:抽象工厂
查看>>
Stackoverflow热门问题
查看>>
Code::Blocks导出MakeFile文件工具
查看>>
HTML 5 的自定义 data-* 属性和jquery的data()方法的使用
查看>>
胖子哥的大数据之路(三)- 大数据仓库的需求分析该怎么做
查看>>
tensorflowDetectionAPI
查看>>
多种网站模板演示
查看>>
JDBC事务处理和保存点
查看>>
前言 -- 数据库准备、一些名词准备
查看>>
Cannot find module '@babel/core'
查看>>
书(一)
查看>>