64位系统下进程的内存布局

http://blog.csdn.net/lyh__521/article/details/50137057

环境

  1. 操作系统:ubuntu15.04
  2. 物理内存:4G

测试程序


#include<stdio.h>
#include<stdlib.h>

int  a;
int  b=1;

main()
{
    int  n = 0;
    char *p1 = NULL;
    char *p2 = NULL;
    const int s = 10;
    p1 = (char*)malloc(200);
    p2 = "hello";

    printf("main  %p\n",main);
    printf("未初始化 a   %p\n",&a);
    printf("初始化   b   %p\n",&b);
    printf("局部变量 n   %p\n",&n);
    printf("动态内存 p1  %p\n",p1);
    printf("常量     s   %p\n",&s);
    printf("常字符串 p2  %p\n",p2);

    while(1)
    {}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

查看内存地址空间方式

以下2种方式可以结合着观察

1、 pmap 命令

pmap [参数] [进程pid]

参数:

  • -d 显示详细设备信息
  • -q 不显示首尾行信息

运行测试程序,用top或ps 命令查询进程pid:

这里写图片描述


属性含义
Address地址空间:起始地址~
Kbytes大小
Mode权限:r可读、w可写、x可执行、s共享内存、p私有内存
Offset虚拟内存偏移量
Device所在设备(主:次): 008:00008表示sda8
mapped虚拟内存分配大小
shared共享内存大小

mem 是运行程序的名字 
.so 是使用的动态链接库 
stack 使用的栈空间 
anon 预分配的虚拟内存,还未有数据占用


2、查看 /proc/pid号/maps 文件内容

这里写图片描述

这个要比上面显示的更详细一点

每一行依次对应的是: 
地址范围、权限、偏移量、设备、文件inode、映射对象

第1行 [可读可执行] 是程序的文本段 
第2行 [只读]………….不清楚 
第3行 [可读可写] 是程序的数据段(包括初始化数据段和未初始化数据段) 
第4行 ………………..堆空间 
第16行 ………………栈空间

vdso 和 vsyscall ……………系统的快速调用 
http://blog.csdn.net/maimang1001/article/details/17331731

用 ls -i 可查看源文件的inode,符合第5列;链接库在根分区下,我的是sda8,源程序在home下,我的是sda8,符合第4列。

3、程序的运行结果

这里写图片描述

从程序的入口地址main 0x400586 可以看出,maps文件的第一行确实是程序的代码段。 

全局变量(初始化和未初始化)位于数据段,对应第3行 

局部变量位于栈段 

const 常量位于栈段 

常字符串位于文本段 

动态申请内存位于堆段 


64位系统中应该有48根地址总线,低位:0~47位才是有效的可变地址,高位:48~63位全补0或全补1。一般高位全补0对应的地址空间是用户态,如上面的第1~18行。高位全补1对应的是内核态,如上面的第19行。这64位的地址空间并不能全部被使用(太多了),所以用户态和内核态之间会有未使用的空间(据说叫AMD64空洞)。

由上图的文件内容可以看出,从低地址到高地址内存布局依次是: 

保留区 –> 文本段–>数据段—>堆—>共享库—>栈–>环境变量—>内核态 

由pmap 命令和maps的显示可看出,栈和堆的中间部分是共享库,栈空间地址减小向下增长,堆空间地址增大向上增长。我觉得堆栈增长的时候,数据会先往紧挨的已分配内存anon中放,anon不够用时再继续增长,新分配内存。


这里写图片描述

dmesg 命令

显示系统启动时的信息

dmesg链接



  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值