【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )
本篇博客调用 sbrk
系统调用函数 , 申请并修改 堆内存 , 并在 /proc/pid/maps 中查看该进程的 堆内存 ;
一、sbrk 内存分配系统调用代码示例
sbrk
系统调用函数 , 作用是 修改程序 BSS 段大小 ;
函数原型如下 :
#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);
函数执行成功 , 返回一个指向 " 堆内存 " 的指针 ;
函数执行失败 , 返回 (void*)-1
返回值 ;
内存地址查找 : 先获取 当前运行的 进程 ID , 也就是 PID , 然后根据 PID 找到 内存地址 ; 如果进程退出 , 也就获取不到 进程的 信息了 , 这里需要有一个死循环 , 保证进程一直存活 ;
// 此处死循环阻塞, 方便查看 /proc/pid/maps 中的信息
// 进程退出后 , 进程相关内存信息也会同时销毁
while (1);
完整代码示例 :
#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 : %d\n", getpid());
// 打印 申请的 堆内存地址 , 发现地址没有变化
printf("p_old : %p \np : %p \n", p_old, p);
// 申请新的 堆内存
int *p_new = sbrk(0);
// 打印新的 堆内存地址
printf("p_new : %p\n", p_new);
// 此处死循环阻塞, 方便查看 /proc/pid/maps 中的信息
// 进程退出后 , 进程相关内存信息也会同时销毁
while (1);
return 0;
}
函数打印结果 :
han@ubuntu:~/vscode/memory$ gcc memory.c
han@ubuntu:~/vscode/memory$ ./a.out
pid : 4829
p_old : 0x203e000
p : 0x203e000
p_new : 0x2060000
进程 ID 为 4829 4829 4829 ;
sbrk
返回的指针 p
, 在第二次申请内存时 , 指针始终没有改变 , 一直都是 0x203e000
地址 ;
如果使用新的指针 p_new
接收 sbrk
系统调用返回的堆内存指针 , 则分配的是新的地址 ;
二、在 /proc/pid/maps 中查看进程堆内存详情
在上一节 , 已经打印出进程的 PID 为 4829 4829 4829 , 根据该 PID , 可以直接获取该进程的内存情况 ,
执行
cat /proc/4829/maps
命令 , 可以打印出指定进程 ID 的内存映射情况 , 打印结果如下 :
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]
相关文章
- 【Linux 内核 内存管理】内存映射相关数据结构 ⑤ ( vm_area_struct 结构体成员分析 | vm_pgoff 成员 | vm_file 成员 | vm_private_data )
- 和交换空间Linux内存管理:剩余内存与交换空间(linux剩余内存)
- 哪些探究Linux内核:从结构到功能(linux内核主要有)
- 如何配置Linux系统的个人电脑(linux电脑配置)
- 深入Linux:C语言软件编程之旅(c语言linux编程软件)
- Linux新突破:最新内核版号5.5上线(linux最新内核版本号)
- 社团开启Linux之门,倾心打造惠州学院社团新生期(惠州学院linux)
- 掌握Linux系统中查看进程的线程知识(linux查看进程的线程)
- 深入理解Linux内核信息(linux内核信息)
- 简单步骤:Linux编译运行快速指南(linux如何编译运行)
- Linux的新型发展:开拓分支(linux的分支)
- 最新Linux内核版本:开创全新技术领域(最新linux内核版本)
- 如何在Linux中关闭命令窗口?(linux关闭命令窗口)
- 探究Linux进程通信机制,解析进程间通讯方式及内核原理,深入了解操作系统运转机制。(linux进程通信机制)
- Linux内核推动云计算进程的发展(linux内核云计算)
- 如何在Linux中打开文件(linux打开一个文件)
- 探究Linux内核,深入讲解系统运作原理(linux内核讲解)
- Linux挂载CIFS共享:细节的一次优化(linux cifs)
- Linux集群确保高可用性的实践(linux集群高可用)
- 助你快速上手Linux内核的视频教程(linux 内核视频教程)
- 版本如何查看Linux内核版本?(怎么查看linux内核)
- Linux编译完美内核,助力智慧未来(linux编译好的内核)
- 优化Linux内存管理:提高系统性能的关键技术(linux内存管理与)