文章目录
- 一、sbrk 内存分配系统调用代码示例
- 二、在 /proc/pid/maps 中查看进程堆内存详情
本篇博客调用 sbrk
系统调用函数 , 申请并修改 堆内存 , 并在 /proc/pid/maps 中查看该进程的 堆内存 ;
一、sbrk 内存分配系统调用代码示例
sbrk
系统调用函数 , 作用是 修改程序 BSS 段大小 ;
函数原型如下 :
代码语言:javascript复制#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);
函数执行成功 , 返回一个指向 " 堆内存 " 的指针 ;
函数执行失败 , 返回 (void*)-1
返回值 ;
内存地址查找 : 先获取 当前运行的 进程 ID , 也就是 PID , 然后根据 PID 找到 内存地址 ; 如果进程退出 , 也就获取不到 进程的 信息了 , 这里需要有一个死循环 , 保证进程一直存活 ;
代码语言:javascript复制 // 此处死循环阻塞, 方便查看 /proc/pid/maps 中的信息
// 进程退出后 , 进程相关内存信息也会同时销毁
while (1);
完整代码示例 :
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
// 使用 sbrk 系统调用申请 堆内存
int *p = sbrk(0);
// 记录该堆内存地址
int *p_old = p;
// 继续为 申请的堆内存, 申请 1024 字节内存
p = sbrk(1024);
// 打印进程 ID , PID
printf("pid : %dn", getpid());
// 打印 申请的 堆内存地址 , 发现地址没有变化
printf("p_old : %p np : %p n", p_old, p);
// 申请新的 堆内存
int *p_new = sbrk(0);
// 打印新的 堆内存地址
printf("p_new : %pn", p_new);
// 此处死循环阻塞, 方便查看 /proc/pid/maps 中的信息
// 进程退出后 , 进程相关内存信息也会同时销毁
while (1);
return 0;
}
函数打印结果 :
代码语言:javascript复制han@ubuntu:~/vscode/memory$ gcc memory.c
han@ubuntu:~/vscode/memory$ ./a.out
pid : 4829
p_old : 0x203e000
p : 0x203e000
p_new : 0x2060000
进程 ID 为
;
sbrk
返回的指针 p
, 在第二次申请内存时 , 指针始终没有改变 , 一直都是 0x203e000
地址 ;
如果使用新的指针 p_new
接收 sbrk
系统调用返回的堆内存指针 , 则分配的是新的地址 ;
二、在 /proc/pid/maps 中查看进程堆内存详情
在上一节 , 已经打印出进程的 PID 为
, 根据该 PID , 可以直接获取该进程的内存情况 ,
执行
代码语言:javascript复制cat /proc/4829/maps
命令 , 可以打印出指定进程 ID 的内存映射情况 , 打印结果如下 :
代码语言:javascript复制han@ubuntu:~/vscode/memory$ cat /proc/4829/maps
00400000-00401000 r-xp 00000000 08:01 3147969 /home/han/vscode/memory/a.out
00600000-00601000 r--p 00000000 08:01 3147969 /home/han/vscode/memory/a.out
00601000-00602000 rw-p 00001000 08:01 3147969 /home/han/vscode/memory/a.out
0203e000-02060000 rw-p 00000000 00:00 0 [heap]
7f3534a9f000-7f3534c5f000 r-xp 00000000 08:01 1723650 /lib/x86_64-linux-gnu/libc-2.23.so
7f3534c5f000-7f3534e5f000 ---p 001c0000 08:01 1723650 /lib/x86_64-linux-gnu/libc-2.23.so
7f3534e5f000-7f3534e63000 r--p 001c0000 08:01 1723650 /lib/x86_64-linux-gnu/libc-2.23.so
7f3534e63000-7f3534e65000 rw-p 001c4000 08:01 1723650 /lib/x86_64-linux-gnu/libc-2.23.so
7f3534e65000-7f3534e69000 rw-p 00000000 00:00 0
7f3534e69000-7f3534e8f000 r-xp 00000000 08:01 1723642 /lib/x86_64-linux-gnu/ld-2.23.so
7f3535074000-7f3535077000 rw-p 00000000 00:00 0
7f353508e000-7f353508f000 r--p 00025000 08:01 1723642 /lib/x86_64-linux-gnu/ld-2.23.so
7f353508f000-7f3535090000 rw-p 00026000 08:01 1723642 /lib/x86_64-linux-gnu/ld-2.23.so
7f3535090000-7f3535091000 rw-p 00000000 00:00 0
7ffc4ac84000-7ffc4aca5000 rw-p 00000000 00:00 0 [stack]
7ffc4ad19000-7ffc4ad1d000 r--p 00000000 00:00 0 [vvar]
7ffc4ad1d000-7ffc4ad1f000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
han@ubuntu:~/vscode/memory$
第一次使用 sbrk
申请的内存地址是 0x203e000
,
第二次还是为 p
指针申请内存 , 实际上是修改 " 堆内存 " 大小 , 其指针的首地址不变 , 是 0x203e000
;
第三次调用 sbrk
申请的是新的内存 , 地址是 0x2060000
;
在 /proc/4829/maps
文件中 , 堆内存的区域是 0203e000-02060000
, 与打印出的值相对应 ;
0203e000-02060000 rw-p 00000000 00:00 0 [heap]