对malloc和free的思考

进程的内存布局:

对malloc和free的思考_第1张图片

Heap的顶端的限制叫做program break,通过系统调用brk活着sbrk可以想内核申请内存从而改变break,也就是增加或收缩heap的大小。

进程的地址空间所面对的都是虚拟地址,kernel为每个进程维护一个page table,建立了虚拟地址空间的页和物理内存页或swap空间的映射(虚拟内存或物理内存都是以页为单位)。

很重要的一个特点是,虚拟地址空间是连续的!

虚拟内存管理有很多好处:1、进程相互之间或进程与内核之间相互隔离,进程不能操作其他进程的内存空间,更不能操作内核的空间。2、多个进程可以共享内存。 (多个进程执行相同的程序,也就是多个进程的text segment所对应的物理内存是同一份),节约内存。3、进程维护的页表可以更容易的实现内存保护。(标记page table的entry即可)

虚拟内存这块让我想到了,“软件的很多问题都可以靠加一个中间层解决”;o(∩_∩)o 哈哈

下面是一个简单的malloc和free实现,通过系统调用sbrk来实现:
实现细节:
    1、在需要的内存块前面追加一小块空间,来存储当前块的大小(貌似都这样)
    2、维护两个全局变量,managed_memory_start、所维护内存的起始地址
        last_valid_address、所维护内存的最后有效地址,也就是program break
    3、free的实现很简单,标记此块为未用

    4、malloc实现,遍历所维护的内存块,找到合适的就返回,找不到就要求系统分配所要求大小的内存。

参考这篇文章:    http://www.ibm.com/developerworks/cn/linux/l-memory/index.html


这个简单的内存管理程序有很多缺点:
1、每一次内存不够时,都要调用sbrk系统调用。sbrk系统调用的单位通常是页大小的很多倍(页典型为4K,sbrk调用最小典型为128K,数据来自于tlpi),这样会有效减少系统调用的次数。
2、malloc中的内存大小匹配算法,找到size>=required的块,会有很多浪费(glibc的实现,则会把大块分裂,返回用户需要的,剩余的放到free list中)。
3、malloc的块查找算法,是遍历整个进程空间,效率太低(glibc是双向链表)。
4、mem_control_block的结构中变量is_available只有一位,确是个int类型,占用空间过多(glibc中只有一个size记录块大小,free块时在块中分配两个指针插入到free list双向链表中)。
5、申请的内存并不会返回给内核(glibc在某种情况下,释放的内存在heap的顶端形成一大片连续的区域,并且大小达到一定的数值(比如128K,数据来自tlpi),尽量减少sbrk系统调用的次数)。

前面,后面最重要的文字总结,都是我自己写的,哈哈~~~


你可能感兴趣的:(linux,malloc,free,glibc,简单实现)