admin 管理员组文章数量: 887021
内存管理
前言
堆内存是linux进程空间中一片可以动态扩展或者伸缩的内存区域,一般位于bss之后。
阅读《嵌入式C语言自我修养》笔记
文章目录
- 前言
- 一、堆内存管理
- 二、linux堆内存管理
- 1.mm_struct
- 2.内存分配器
- 3.ptmalloc2
主要有以下几个函数:
#include<stdio.h>
void *malloc(int size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr,size_t size); /*可以调整内存的大小*/
对于着四个函数的用法,可以百度。
一、堆内存管理
一般在裸机环境下,在经过多次申请和释放堆内存后,会有越来越多的碎片内存,致使后续申请失败,所以在裸机环境中,很少见到使用堆内存的。绝大多数还是通过操作系统进行管理。
二、linux堆内存管理
1.mm_struct
对于用户申请小内存块,会在bss段的后面批准一块内存给内存使用;当大于128KB时,则需要通过mmap系统调用,映射一片内存给用户使用,映射区域在用户进程栈附近。
在每一个linux用户进程中,linux内核都会使用一个task_struct 结构体描述,其中,有mm_struct结构体,用来描述该进程的代码段,数据段,堆栈的起始地址。
struct mm_struct{
....
unsigned long mmap_base;
unsigned long start_code,end_code,start_data,end_data;
unsigned long start_brk,brk,start_stack;
unsigned long arg_start,arg_end,env_start,env_end;mm_context_t contest;
...
}
start_brk 是便是堆区的起始地址,brk则是结束边界地址。当用户malloc()申请堆区大小大于当前堆区时,malloc()通过brk()系统调用,修改brk的地址,来改变大小。
2.内存分配器
为了减小系统调用的次数,提高效率,可以在用户层面对堆内存介入管理。
内存分配器通过系统调用brk()/mmap()向linux内存管理子系统“批发”内存,同时实现了malloc()/free(),供用户使用。
当用户使用free()释放内存时,释放的内存并不立即返回给内核,而是通过内存分配器缓存在用户空间,通过链表收集起来,等下次用户在申请时,查找合适大小的,如果没有,再去brk()系统调用。
3.ptmalloc2
深入理解 glibc malloc:内存分配器实现原理
Glibc内存管理-ptmalloc2
内存管理:malloc的bin和特殊chunk
Linux下的c标准库glibc使用ptmalloc2作为内存分配器。对于用户申请的每一个内存块都叫成chunk:
struct malloc_trunk
{INTERNAL_SIZE_T mchunk_prev_size;INTERNAL_SIZE_T mchunk_size;struct malloc_chunk* fd;struct malloc_chunk* bk;struct malloc_chunk* fd_nextsize;struct malloc_chunk* bk_nextsize;
}
用户释放掉的内存并不是马上就归还给操作系统,ptmalloc会统一管理heap和mmap映射区中的空闲的chunk,当用户进行下一次请求分配时,ptmalloc会试图从空闲的内存中挑选一块给用户,这样可以避免频繁的系统调用,降低了内存分配的开销。ptmalloc将大小相似的chunk用双向循环链表连接起来,这样的一个链表称为bin。ptmalloc中一共维护了128个bin,并使用一个数组来存储这些bin(数组实际存储的是指针)。
用户释放掉的内存块不会立即放到bins中,而是先放到unsorted bin 上,等下次申请会先在中查看有没有合适的。在free small bin和large bin后,free chunk会被放入unsorted bin中,这样可以加快内存的分配和释放操作,因为不需要花费额外的时间去查找合适的bin了
分类 | 数组索引 | 内存块大小 | 步长 | 个数 |
---|---|---|---|---|
unsorted bin | - | - | 1 | |
small bins | [2,63] | [16,504] | 8 | 62 |
small bins | [64,94] | [512,2488] | 64 | 31 |
small bins | [95,111] | [2496,10744] | 512 | 17 |
small bins | [112,120] | [10752,45048] | 4096 | 9 |
small bins | [121,123] | [45056,163832] | 32768 | 3 |
small bins | [124,126] | [163840,786424] | 262144 | 3 |
small bins | [127] | [786432,2^64] | - | 1 |
还有一些bins,如fast bin,用户释放掉的内存块小于M_NAXFAST(32位默认64字节)会首先放到fast bin.
总的讲:
当用户申请一块内存时,内存分配器就根据申请内存的大小从bins查找合适的内存块。当然这些零碎的内存块也会在合适的情况下合并。
当用户申请大于128KB内存,则需要mmap.
Linux内存分配小结–malloc、brk、mmap
本文标签: 内存管理
版权声明:本文标题:内存管理 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1686618105h17778.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论