博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程的虚拟地址空间
阅读量:6226 次
发布时间:2019-06-21

本文共 2739 字,大约阅读时间需要 9 分钟。

进程的虚拟地址空间

转载:

1.内核空间

一般可以通过__get_free_page()kmalloc()vmalloc()来申请内核空间。只不过__get_free_page函数每次申请的都是完整的页;而后两者则依据具体参数申请以字节为单位的内存空间。此外,前两个函数申请的虚拟地址空间和物理地址空间都是连续的;vmalloc函数申请的物理地址空间并不连续。vmalloc函数通过重新建立虚拟地址空间和物理地址空间之间的映射,即新建页表项,将离散的物理地址空间映射到连续的虚拟地址空间。因此,使用该函数的开销比较大。

下面的程序简单的演示了这三个函数的使用方法。从结果中可以看出,这些函数申请的地址都在3GB(0xBFFFFFFF)以上。

static int __init mmshow_init(void){    printk("mmshow module is working\n");    pagemem = __get_free_page(GFP_KERNEL);    if(!pagemem)        goto gfp_fail;    printk(KERN_INFO "pagemem = 0x%lx\n",pagemem);    kmallocmem = kmalloc(100 * sizeof(char),GFP_KERNEL);    if(!kmallocmem)        goto kmalloc_fail;    printk(KERN_INFO "kmallocmem = 0x%p\n",kmallocmem);    vmallocmem = vmalloc(1000000 * sizeof(char));    if(!vmallocmem)        goto vmalloc_fail;    printk(KERN_INFO "vmallocmem = 0x%p\n",vmallocmem);    return 0;gfp_fail:    free_page(pagemem);kmalloc_fail:    kfree(kmallocmem);vmalloc_fail:    vfree(vmallocmem);    return -1;}//运行结果:[ 5542.073900] mmshow module is working[ 5542.073904] pagemem = 0xf3211000[ 5542.073907] kmallocmem = 0xd581e700[ 5542.073983] vmallocmem = 0xf9251000

2.用户空间

如前所述,每个进程够拥有属于自己的3GB的虚拟空间,那么这个3GB的空间是如何划分的?通常,除了我们熟悉的代码段和数据段,用户空间还包括堆栈段和堆。我们可以通过下面的演示程序来了解这些区域到底负责存储程序的那些内容。

int bss_var;int data_var0 = 1;int main(int argc,char **argv){    printf("The user space's address division of a process as follow:\n");    printf("Data segment:\n");    printf("address of \"main\" function:%p\n\n",main);        printf("Data segment:\n");    printf("address of data_var:%p\n",&data_var0);    static int data_var1 = 4;    printf("new end of data_var:%p\n\n",&data_var1);        printf("BSS:\n");    printf("address of bss_var:%p\n\n",&bss_var);    char *str = (char *)malloc(sizeof(char)*10);    printf("initial heap end:%p\n",str);    char *buf = (char *)malloc(sizeof(char)*10);    printf("new heap end:%p\n\n",buf);        int stack_var0 = 2;    printf("Stack segment:\n");    printf("initial end of stack:%p\n",&stack_var0);    int stack_var1 = 3;    printf("new end of stack:%p\n",&stack_var1);    return 0;}//运行结果:The user space's address division of a process as follow:Data segment:address of "main" function:0x8048454Data segment:address of data_var:0x804a01cnew end of data_var:0x804a020BSS:address of bss_var:0x804a02cinitial heap end:0x8f77008new heap end:0x8f77018Stack segment:initial end of stack:0xbfe0a3b4new end of stack:0xbfe0a3b0

可以看到,代码段存放程序的代码;数据段存放全局变量和static类型的局部变量。此外,未初始化的全局变量虽然也存在于数据段,但是这些未初始化的变量都集中在靠近数据段上边界的区域,这个区域称为BSS段。以上这些空间是进程所必须拥有的,它们在进程运行之前就分配好了。

程序中的局部变量一般被分配在堆栈段,其位于用户空间最顶部。与固定的代码段和数据段不同的是,堆栈段存储数据是从高低值往低地址延伸的。因此,在数据段到堆栈段之间,形成了一片空洞,这片空洞用于存储malloc函数所动态分配的空间,这片空洞区域被称为堆。

通过下面这个图可以更进一步的了解到进程用户空间的划分情况。

转载于:https://www.cnblogs.com/muahao/p/7526189.html

你可能感兴趣的文章
【洛谷 P4342】[IOI1998]Polygon(DP)
查看>>
流程管理软件(BPM)功能简介
查看>>
0408 汉堡包
查看>>
记一次服务器被勒索!
查看>>
docker jenkins安装(一)
查看>>
linux安装软件的几种方法
查看>>
HTML5系列:HTML5表单
查看>>
团队编程项目作业2-爬虫豆瓣top250项目代码设计规范
查看>>
Oracle觸發器調用procedure寄信
查看>>
练习-为网页添加icon图标;为网页添加关键字/作者;超链接;input的type属性有哪些常用属性值-form表单...
查看>>
实验一
查看>>
单页数据多iOS预加载的方法
查看>>
acm计划(更新于2014.11.9)
查看>>
hdu3364 高斯消元1(开关控制灯,异或解的个数)
查看>>
Python网络编程1:套接字
查看>>
Complete Physics Platformer Kit 学习
查看>>
软件工程---删除重复数组
查看>>
ubuntu16 64 搭建lnmp环境
查看>>
数据结构中的图
查看>>
设计模式:结构型模式总结
查看>>