原文: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.合并

  

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

  

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

  

  

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

【转载】malloc内存分配与free内存释放的原理的更多相关文章

  1. malloc内存分配与free内存释放的原理

    malloc内存分配与free内存释放的原理 前段时间一直想看malloc的原理,在搜了好几篇malloc源码后遂放弃,晦涩难懂. 后来室友买了本深入理解计算机系统的书,原来上面有讲malloc的原理 ...

  2. SQL SERVER 内存分配及常见内存问题(2)——DMV查询

    原文:SQL SERVER 内存分配及常见内存问题(2)--DMV查询 内存动态管理视图(DMV): 从sys.dm_os_memory_clerks开始. SELECT [type] , SUM(v ...

  3. SQL SERVER 内存分配及常见内存问题(1)——简介

    原文:SQL SERVER 内存分配及常见内存问题(1)--简介 一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解 ...

  4. (转)java内存分配分析/栈内存、堆内存

    转自(http://blog.csdn.net/qh_java/article/details/9084091) java内存分配分析/栈内存.堆内存 java内存分配分析 本文将由浅入深详细介绍Ja ...

  5. rt-thread中动态内存分配之小内存管理模块方法的一点理解

    @2019-01-18 [小记] rt-thread中动态内存分配之小内存管理模块方法的一点理解 > 内存初始化后的布局示意 lfree指向内存空闲区首地址 /** * @ingroup Sys ...

  6. 目录_Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)

    1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘 ...

  7. Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:什么是静态内存什么又是动态内存呢? 静态内存:是指在程序开始运行时由编译 ...

  8. C程序的内存分配及动态内存

    1.程序内存的分配 一个由C/C++编译的程序占用的内存分为以下几个部分:1)栈区(stack) — 由编译器自动分配释放 , 存放为运行函数而分配的局部变量. 函数参数. 返回数据. 返回地址等. ...

  9. SQL SERVER 内存分配及常见内存问题 简介

    一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解SQL SERVER与windows是如何协调.共享内存.并且SQ ...

  10. C++_类和动态内存分配1—动态内存和类

    静态类成员 num_strings成员声明为静态存储类.静态类成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象共享一个静态成员.num_strings成员可以 ...

随机推荐

  1. eclipse工具的安装配置

    安装环境 系统:Windows7 软件:jre-8u73-windows-x64.exe,eclipse-inst-win64.exe Eclipse的安装过程 1.安装jre-8u73-window ...

  2. python入门の缩进魔术

    idx=1 sum=0 while idx<=100: sum=idx+sum idx=idx+1 print('sum 100 =', sum) ======================= ...

  3. [C++] 用Xcode来写C++程序[3] Constants

    用Xcode来写C++程序[3] Constants 以下是一些基本数据的含义: 75 // int 75u // unsigned int 75l // long 75ul // unsigned ...

  4. Python入门-模块4(序列化----json模块和pickle模块)

    序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes.反之,把硬盘里面的数据读到内存里,叫反序列化.

  5. [原创]获取JS数组最大值、最小值

    核心关键 JS有Array数组对象,使用prototype内置属性扩展,增加Array数组max().min()方法 具体代码 //最小值 Array.prototype.min = function ...

  6. linux中ftp提示--553 Could not create file

    今天在阿里云的linux上搭建ftp服务的时候,搭建成功之后,上传文件时总提示553 Could not create file,找了半天原因,终于解决了 ftp主目录为/home/myftp /ho ...

  7. C# 算法题系列(一) 两数之和、无重复字符的最长子串

    题目一 原题链接 https://leetcode-cn.com/problems/two-sum/ 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整 ...

  8. CI(2.2) 配置 jquery的上传插件Uploadify(v3.2) 上传文件

    1.下载uploadify,   我的是v3.2 2.模板页面引入: <base href='{base_url()}' /> <script type="text/jav ...

  9. Linux 下安装配置 JDK7 配置环境(debian 7)

    自从从Oracle收购Sun近三年来,已经有很多变化.早在8月,甲骨文将“Operating System Distributor License for Java”许可证终结,这意味着第三方将不可以 ...

  10. 理解JavaScript继承(三)

    理解JavaScript继承(三) 通过把父对象的属性,全部拷贝给子对象,也能实现继承. 7.浅拷贝 function extendCopy(p) { var o = {}; for (var pro ...