【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )
文章目錄
- 一、sbrk 內(nèi)存分配系統(tǒng)調(diào)用代碼示例
- 二、在 /proc/pid/maps 中查看進程堆內(nèi)存詳情
本篇博客調(diào)用 sbrk 系統(tǒng)調(diào)用函數(shù) , 申請并修改 堆內(nèi)存 , 并在 /proc/pid/maps 中查看該進程的 堆內(nèi)存 ;
一、sbrk 內(nèi)存分配系統(tǒng)調(diào)用代碼示例
sbrk 系統(tǒng)調(diào)用函數(shù) , 作用是 修改程序 BSS 段大小 ;
函數(shù)原型如下 :
#include <unistd.h> int brk(void *addr); void *sbrk(intptr_t increment);函數(shù)執(zhí)行成功 , 返回一個指向 " 堆內(nèi)存 " 的指針 ;
函數(shù)執(zhí)行失敗 , 返回 (void*)-1 返回值 ;
內(nèi)存地址查找 : 先獲取 當前運行的 進程 ID , 也就是 PID , 然后根據(jù) PID 找到 內(nèi)存地址 ; 如果進程退出 , 也就獲取不到 進程的 信息了 , 這里需要有一個死循環(huán) , 保證進程一直存活 ;
// 此處死循環(huán)阻塞, 方便查看 /proc/pid/maps 中的信息// 進程退出后 , 進程相關(guān)內(nèi)存信息也會同時銷毀while (1);完整代碼示例 :
#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char* argv[]) {// 使用 sbrk 系統(tǒng)調(diào)用申請 堆內(nèi)存int *p = sbrk(0);// 記錄該堆內(nèi)存地址int *p_old = p;// 繼續(xù)為 申請的堆內(nèi)存, 申請 1024 字節(jié)內(nèi)存p = sbrk(1024);// 打印進程 ID , PID printf("pid : %d\n", getpid());// 打印 申請的 堆內(nèi)存地址 , 發(fā)現(xiàn)地址沒有變化printf("p_old : %p \np : %p \n", p_old, p);// 申請新的 堆內(nèi)存int *p_new = sbrk(0);// 打印新的 堆內(nèi)存地址printf("p_new : %p\n", p_new);// 此處死循環(huán)阻塞, 方便查看 /proc/pid/maps 中的信息// 進程退出后 , 進程相關(guān)內(nèi)存信息也會同時銷毀while (1);return 0; }函數(shù)打印結(jié)果 :
han@ubuntu:~/vscode/memory$ gcc memory.c han@ubuntu:~/vscode/memory$ ./a.out pid : 4829 p_old : 0x203e000 p : 0x203e000 p_new : 0x2060000進程 ID 為 482948294829 ;
sbrk 返回的指針 p , 在第二次申請內(nèi)存時 , 指針始終沒有改變 , 一直都是 0x203e000 地址 ;
如果使用新的指針 p_new 接收 sbrk 系統(tǒng)調(diào)用返回的堆內(nèi)存指針 , 則分配的是新的地址 ;
二、在 /proc/pid/maps 中查看進程堆內(nèi)存詳情
在上一節(jié) , 已經(jīng)打印出進程的 PID 為 482948294829 , 根據(jù)該 PID , 可以直接獲取該進程的內(nèi)存情況 ,
執(zhí)行
cat /proc/4829/maps命令 , 可以打印出指定進程 ID 的內(nèi)存映射情況 , 打印結(jié)果如下 :
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 申請的內(nèi)存地址是 0x203e000 ,
第二次還是為 p 指針申請內(nèi)存 , 實際上是修改 " 堆內(nèi)存 " 大小 , 其指針的首地址不變 , 是 0x203e000 ;
第三次調(diào)用 sbrk 申請的是新的內(nèi)存 , 地址是 0x2060000 ;
在 /proc/4829/maps 文件中 , 堆內(nèi)存的區(qū)域是 0203e000-02060000 , 與打印出的值相對應(yīng) ;
0203e000-02060000 rw-p 00000000 00:00 0 [heap]總結(jié)
以上是生活随笔為你收集整理的【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux 内核 内存管理】内存管理架
- 下一篇: 【Linux 内核 内存管理】虚拟地址空