前几天同事遇到一个问题,程序启动加载所有的功能模块,后续通过接口调用卸载了一些功能模块,但是在资源占用测试时,发现卸载前后比较,只有cpu使用率下降了,但是内存占用没有下降,这比较奇怪,卸载模块时明明已经free掉了申请的内存的啊,可是内存占用还是没有下降喃?于是我开始去搜索了相关的问题,发现果然大有门道啊。
虚拟内存空间
先说说虚拟内存,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的处理器,地址空间的范围也不同。以32位处理器为例,如下如所示:
在用户空间,从高到低分别为
- 栈,主要为局部变量,大小一般固定为8MB
- 文件映射段,主要为动态库、共享内存等
- 堆,主要为动态分配的内存,从低地址往高地址增长
- 数据段,主要为全局变量
- 只读段,主要为常量和代码
malloc对应的系统调用
在我们使用malloc在堆中动态分配内存时,实际上会设计到两种系统调用,分别为brk和mmap。
这两种系统调用是有区别的:
brk
当我们申请的内存大小小于128k时,标准库会调用brk来分配,它是将堆顶移动的方式进行的。如下如所示:
mmap
而申请的内存大小大于128k时,会调用mmap内存映射来分配,即在文件映射段找一块空闲的内存进行分配。如下如所示: