前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )

【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )

作者头像
韩曙亮
发布2023-03-30 14:19:08
4K0
发布2023-03-30 14:19:08
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

本篇博客调用 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 : %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;
}

函数打印结果 :

代码语言: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 为

4829

;

sbrk 返回的指针 p , 在第二次申请内存时 , 指针始终没有改变 , 一直都是 0x203e000 地址 ;

如果使用新的指针 p_new 接收 sbrk 系统调用返回的堆内存指针 , 则分配的是新的地址 ;

二、在 /proc/pid/maps 中查看进程堆内存详情


在上一节 , 已经打印出进程的 PID 为

4829

, 根据该 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 , 与打印出的值相对应 ;

代码语言:javascript
复制
0203e000-02060000 rw-p 00000000 00:00 0                                  [heap]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、sbrk 内存分配系统调用代码示例
  • 二、在 /proc/pid/maps 中查看进程堆内存详情
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档