[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系)

这篇具有很好参考价值的文章主要介绍了[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

hello,大家好,这里是bang_bang,今天我们来讲一下语言层级上的程序地址空间和系统层级上的进程地址空间的区别,在下面中我举的例子会设计到环境变量,所以开篇我先讲讲环境变量。

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

目录

1️⃣环境变量

🍙 基本概念

🍙环境变量相关命令

🍥查看环境变量echo

🍥添加全局环境变量export

🍥显示环境变量env/set

🍥清除环境变量unset

🍥全局与局部环境变量对比

🍥系统调用getenv获取特定环境变量

🍥系统定义全局变量environ

🍥浅谈main函数参数及environ的使用

2️⃣进程地址空间

🍙程序地址空间(语言层级)

🍥验证地址空间排布

🍥探究物理内存or虚拟内存

🍙进程地址空间(系统层级)

🍥地址空间发展由来

🍥地址空间结构

🍥地址空间与物理内存的联系

🍥写时拷贝

🍥编译器同样遵守虚拟地址

🍙 为什么需要进程地址空间

🍥安全性

🍥独立性

🍥分批加载and分批换出


1️⃣环境变量

初识:

        大家在Linux下执行自己写的程序的时候不知道有没有注意到一个细节。命令行是这样的:

[roothost]$ ./可执行程序文件名

 ./ 是当前路径,也就是说我们要执行我们的程序需要带上路径!!!

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

        那么有没有方法可以让我们的程序执行不需要带路径,而是像系统命令一样,直接输入命令执行呢?

——这就需要环境变量了!!!

🍙 基本概念

⭐环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
⭐环境变量通常具有某些特殊用途,还有在系统当中通常具有 全局特性
常见环境变量:
        ★ PATH : 指定命令的搜索路径
        ★ HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
        ★ SHELL : 当前Shell,它的值通常是/bin/bash。

🍙环境变量相关命令

🍥查看环境变量echo

echo $NAME    //NAME是你的环境变量名称

🌰查看环境变量PATH 

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

如何直接使我们写的程序不用带上路径,像系统命令一样执行?

我们可以在PATH路径下加入我们这个可执行程序文件的当前路径。

🍥添加全局环境变量export

命令行改环境变量,只在本次登陆中生效。环境变量具有全局性!

export将环境变量设置为全局环境变量

export NAME=$NAME:添加的路径   //添加环境变量  export全局

$NAME:表示在原路径后增加路径

目录之间用冒号(:)隔开

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🍥显示环境变量env/set

env        //显示全局环境变量
set        //显示本地shell变量和环境变量

这2条命令显示的结果太长,这里就不贴了,小伙伴们可以自己在Linux中使用查看结果。

查看env和set的详细信息可以使用 man命令进行查看

man set
man env

🍥清除环境变量unset

unset NAME        //NAME为要清除的变量 

 🌰清除环境变量XDG_SESSION_ID

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🍥全局与局部环境变量对比

局部环境变量只能在当前shell中使用,无法在子shell中使用。(局部性)

创建局部shell变量

NAME=内容            //创建shell变量,局部性

🌰创建一个AAA的局部环境变量

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🌰创建一个HOST的全局环境变量

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🍥系统调用getenv获取特定环境变量

#include <stdlib.h>
char *getenv(const char *name);

🌰获取PATH环境变量

#include<stdio.h>
#include<stdlib.h>
int main()
{
    printf("PATH:%s\n",getenv("PATH"));
    return 0;
}

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🍥系统定义全局变量environ

#include<unistd.h>
extern char **environ;

environ是C语言提供的一个全局变量,其指向环境表,环境表是一个字符指针数组,每个指针指向以'\0‘结尾的环境字符串。注意:环境表最后是NULL

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

🍥浅谈main函数参数及environ的使用

前两个参数是命令行参数,最后一个参数是环境变量参数。 

 int main(int argc, char *argv[], char *env[])

 🌰测试命令行参数:argc是命令参数个数(命令本身算1个参数),字符指针数组argv存放命令

//测试argv[]
int main(int argc,char* argv[])
{
   if(argc != 2)
   {
       printf("Usage: %s 至少要有一个选项\n", argv[0]);
       return 1;
   }

   if(strcmp("-a", argv[1]) == 0)
   {
       printf("这个是功能一\n");
   }
   else if(strcmp("-b", argv[1]) == 0)
   {
       printf("这个是功能二\n");
   }
   return 0;
}

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出


🌰测试环境变量参数:

#include<stdio.h>

int main(int argc,char* argv[],char* env[])
{
    for(int i=0;env[i];i++)
    {
        printf("env[%d]:%s\n",i,env[i]);
    }
    return 0;
}

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出


 🌰使用系统定义变量environ测试:

#include<stdio.h>
#include<unistd.h>
int main(int argc,char* argv[],char* env[])
{
    extern char** environ;
    
    for(int i=0;environ[i];i++)    //环境表最后是NULL,可以直接做for的循环退出条件
    {
        printf("environ[%d]:%s\n",i,environ[i]);
    }
    return 0;
}

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

2️⃣进程地址空间

🍙程序地址空间(语言层级)

相信大家无论在学习何种语言的时候都听说过“地址”这个概念,但不知道大家有没有仔细想过这个“地址”有没有可能不是物理内存上的呢? 

在这里我明确的告诉大家,语言上说的“地址“不是物理内存地址,而是虚拟内存地址!!!

🍥验证地址空间排布

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出
32位下地址空间

🌰测试各区域地址空间排布:

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

int g_unval;
int g_val = 100;


int main(int argc, char *argv[], char *env[])
{
    //字面常量
    const char *str = "helloworld";
    //代码区
    printf("code addr: %p\n", main);
    //位于代码区和全局初始化数据之间(有的教材叫常量区)
    printf("constant addr:%p\n",str);
    //全局初始化数据
    printf("init global addr: %p\n", &g_val);
    static int test = 10;

    printf("test static addr: %p\n", &test);
    //全局未初始化数据
    printf("uninit global addr: %p\n", &g_unval);
    
    char *heap_mem = (char*)malloc(10);
    char *heap_mem1 = (char*)malloc(10);
    char *heap_mem2 = (char*)malloc(10);
    char *heap_mem3 = (char*)malloc(10);
    //堆
    printf("heap addr: %p\n", heap_mem); //heap_mem(0)
    printf("heap addr: %p\n", heap_mem1); //heap_mem(1)
    printf("heap addr: %p\n", heap_mem2); //heap_mem(2)
    printf("heap addr: %p\n", heap_mem3); //heap_mem(3)
    //栈
    printf("stack addr: %p\n", &heap_mem); //&heap_mem(0)
    printf("stack addr: %p\n", &heap_mem1); //&heap_mem(1)
    printf("stack addr: %p\n", &heap_mem2); //&heap_mem(2)
    printf("stack addr: %p\n", &heap_mem3); //&heap_mem(3)
    //命令行参数环境变量
    for(int i = 0 ;i < argc; i++)
    {
        printf("argv[%d]: %p\n", i, argv[i]);
    }
    for(int i = 0; env[i]; i++)
    {
        printf("env[%d]: %p\n", i, env[i]);
    }

    return 0;
}
[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出
验证结果讲解图

进程地址空间分为:正文代码、初始化数据、未初始化数据、堆、栈、命令行参数环境变量,其中堆、栈相对而生。

static修饰局部变量(本质:将该变量开辟在全局区域)

🍥探究物理内存or虚拟内存

我上面一开始就说语言上的地址是虚拟地址,为什么?

🌰下面代码中,我们仔细观察全局变量g_val,在进程中,我们讲过子进程和父进程共享代码

     那g_val理论上应该是一模一样的,实际中是这样吗?

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int g_val=10;

int main()
{
    pid_t id=fork();
    if(id==0)
    {
        //child
        g_val=100;
        printf("child:pid:%d,val:%d,addr:%p\n",getpid(),g_val,&g_val);
    }
    else if(id>0)
    {
        //parent
        printf("parent:pid:%d,val:%d,addr:%p\n",getpid(),g_val,&g_val);
    }
    return 0;
}

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

这怎么可能!这说明语言层级的地址一定不是物理内存地址,而是虚拟内存地址!

🍙进程地址空间(系统层级)

所以之前说的程序地址空间并不准确,准确的应该称作进程地址空间。

虚拟地址肯定不止一份,每一个进程都会有一个虚拟地址,所以它会被管理,那么管理本质又回到了先描述再管理。那么虚拟地址我们猜一定也是一种数据结构!

🍥地址空间发展由来

历史计算机,程序直接放到物理内存,进程中如果出现野指针或者指针指向另一个进程,可以直接读取另一个进程的内容,十分不安全。并且当物理内存满的时候,再插入进程,需要重新排序,十分繁琐。

现代计算机,提出了下面的方式!

——给每个进程一个虚拟地址空间(本质:一个数据结构)(0x0000 0000~0xFFFF FFFF)

🍥地址空间结构

地址空间是一种内核数据结构mm_struct,进程控制块(PCB)包含着mm_struct数据结构的指针

根据上面验证的地址空间排布,我们得知mm_strcut内至少要有各区域的划分,那么是如何实现划分呢?我来讲个小故事引导大家理解。

上小学的时候,我们应该都见过三八线(或者正是你的亲身经历),当你和同桌小美闹矛盾的时候,五五开的桌子变会被重新划分,中间划分的线便是三八线。

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

不难看出,划分的本质就是使用2个数作为两边界+或者-去一定的范围作划分区域。

mm_struct同样如此,通过2个数确定上下边界来划分区域。

我们可以猜测mm_struct是这样定义的:

struct addr_room
{
    int code_start;
    int code_end;
    
    int init_start;
    int init_end;

    int uninit_strat;
    int uninit_end;

    int heap_start;
    int heap_end;
    
    int stack_start;
    int stack_end;

    其他属性;
}

Linux源码中mm_struct结构体部分定义:

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

所谓的区域划分(也就是范围变化),本质是对start或者end标记值+-特定的范围即可!!!

🍥地址空间与物理内存的联系

地址空间和物理内存是通过页表映射联系起来的!

我们的程序是在磁盘中的,当要运行这个程序的时候,程序就会被加载到物理内存中,CPU寻虚拟地址,通过页表映射找到对应的物理地址,读取数据。

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

上篇文章进程详解中,我们提到进程具有独立性!如何实现呢? 

其实只需要我们每个进程都有一份自己的地址空间和页表就可以做到进程彼此分开独立运行!

OS是通过什么机制给每个进程都分配独属于自己的地址空间呢?

        通俗的讲是'画饼',32位的物理内存有4G,OS欺骗每个进程,我物理内存的4G是独属于你的,每个进程往往需要的空间都是很少的,想想你平时写的程序才多大(可能不会超过几Kb),OS自然很乐意的分配给这个进程,但当这个进程需要的空间过大(比如:正好4个G),OS肯定会拒绝,因为它还要管理其他的进程,但是这个进程平时申请的空间OS又都允许了,进程仍旧认为他拥有全部内存的使用权。

如果上面讲的你很难理解,那就看我接下来描述的生活例子,有助于你理解刚刚所说。

        我们在电影中曾看到过富豪在即将去世的时候,会把家产继承给自己的孩子。

        假如现在就有一个富豪,他的家产有4个亿,并且他有3个孩子,3个孩子彼此都认为自己是富豪唯一的孩子,这3个孩子为了子承父业,各自在不同的行业上努力拼搏,平时的一些必要小花销投资向富豪申请,富豪也会同意,但是当有一天,老大向富豪要3个亿去投资大项目,富豪肯定会拒绝他(已经没这么多钱了),老大或许只会抱怨几句,但他还是深信不疑自己就是富豪唯一的孩子,这就是吃了富豪画的饼。

为什么地址空间要被管理?

        你可以想象,一个公司企业的老板,给A员工说你好好干活,我给你加薪;给B员工说你好好干活,我给你升职......画的饼多了,他很有可能会记错,等再给A员工画饼的时候,给他说我给你升职(A员工一定会满脸???之前不是说给我加薪吗)所以为了防止出现错误,老板一定会通过某种手段管理给员工画的饼。

        OS同样如此,他给每个进程画饼,也需要管理,这就回到了上面说的地址空间需要被管理,管理的本质又是先描述再管理。

🍥写时拷贝

会到上面我们探究的例子,地址相同却有2个不同的值!这里面其实发生了一个机制:写时拷贝

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

我们在上篇文章中说父子进程代码和数据是共享的,也就是说父子进程的地址空间通过页表映射到物理内存上应该是一个位置(这是对的!)但是当我们子进程要进行写入的时候,这时为了不影响父进程的数据,OS就会在内存中拷贝出一个新的位置,同时断开页表的映射关系,让页表映射到这个新的位置,供子进程使用。

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

子进程执行读权限的时候,父子进程页表映射到同一物理内存,当执行写权限时,OS重新拷贝一份数据到物理内存上,同时子进程的页表断开原来的映射关系,映射到拷贝数据的物理地址。

🍥编译器同样遵守虚拟地址

地址空间不要仅仅理解成为是OS内部要遵守的,其实编译器也要遵守!!

编译器编译代码的时候,就已经给我们形成了 各个区域 代码区,数据区........并且,采用和Linux内核中一样的编址方式,给每一个变量,每一行代码都进行了编址,故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址!!!

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

CPU读取指令的时候寻址如下:

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出

CPU读取到指令的时候指令内部也有虚拟地址,CPU读取到指令内部的虚拟地址再用该虚拟地址通过页表映射找到数据的物理地址。

🍙 为什么需要进程地址空间

🍥安全性

凡是非法的访问或者映射,OS都会识别到,并终止你这个进程!!(富翁拒绝4个亿的请求)

有效保护了物理内存。也有效的保护了物理内存中的所有有效数据以及内核的相关有效数据!

        比如:修改字符常量区,页表管理的代码区没有写权限。

所有的进程崩溃,本质是进程退出!(OS杀掉这个进程)

🍥独立性

因为有地址空间的存在,页表的映射的存在。我们的物理内存中可以对未来的数据进行任意位置的加载。物理内存的分配就可以和进程的管理,可以做到没有关系!(不关心数据所在物理内存位置,只关心能否映射到物理内存对应位置)

[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系),我在地球学Linux,linux,环境变量,写时拷贝,地址空间,虚拟地址+页表,挂起,加载与换出 内存管理模块 vs 进程管理模块就完成了解耦合!(减少模块和模块的关联性

因为在物理内存中理论上可以任意位置加载,那么物理内存中的所有的数据和代码在内存中是乱序的!但是,因为页表的存在,它可以将地址空间上的虚拟地址和物理地址进行映射,那么在进程视角所有的内存分布,都可以是有序的!

地址空间+页表的存在 可以 将内存分布 有序化!

地址空间是OS给进程画的大饼+任意加载:进程要访问的物理内存中的数据和代码,可能目前并没有在物理内存中,同样的,也可以让不同的进程映射到不同的物理内存,便很容易做到,进程独立性的实现!!

    进程的独立性,可以通过地址空间+页表的方式实现。

    因为有地址空间的存在,每一个进程都认为自己独占内存4G(32)空间,并且各个区域是有序的,进而可以通过页表映射到不同的区域,来实现进程的独立性!!

🍥分批加载and分批换出

我们在C、C++new,malloc空间的时候,本质是在虚拟地址空间申请的。

        本质上,(因为有地址空间的存在,所以上层申请空间,其实是在地址空间上申请的,物理内存可以甚至一个字节都不给。而当你真正进行对物理地址空间访问的时候,才执行内存的相关管理算法,帮你申请内存,构建页表映射关系)延迟分配策略(页表中断),然后,再让你进行内存的访问。

        通过延迟分配策略我们可以实现分批加载, 我们下载的大型程序(几个G)实际上就运用了分批加载的方式,要不然超过了我们的物理内存大小,我们是如何下载下来的?

加载本质就是 创建进程,但不是必须飞的立马把所有的的程序的代码和数据加载到内存中并创建内核数据结构建立映射关系。在最极端的情况下:只有内核结构被创建出来!进程这种状态叫做新建状态!

既然可以分批加载,可以分批换出吗?

        当然可以,甚至这个进程短时间不会再被执行了(比如网络太卡了,要等很久,OS不想让该进程的数据和代码占着位置,那么就换出),进程的数据和代码被换出了,就叫做挂起


文末结语,本篇文章详细讲解了探究地址空间排布的前言知识环境变量,通过程序验证了地址空间排布,并探究程序所说的地址究竟是物理地址还是虚拟地址,铺垫完后进入重点进程地址空间,详细介绍了进程地址空间是什么?结构,与物理内存的联系,并讲解写时拷贝的现象,拓展补充编译器同样遵守虚拟地址;最后讲解为什么需要地址空间,分为3个部分:安全性,独立性和OS的延迟分配策略实现内存的分批换出and分批换入。文章来源地址https://www.toymoban.com/news/detail-610565.html

到了这里,关于[Linux]环境变量 进程地址空间(虚拟内存与物理内存的关系)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux内存管理 | 四、物理地址空间设计模型

    我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 前面几篇文章,主要讲解了虚拟内存空间的布局和管理,下面同步来聊聊物理内

    2024年02月08日
    浏览(45)
  • 命令行参数环境变量和进程空间地址

    正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能 学习网站, 通俗易懂,风趣幽默 ,忍不住分享一下给大家。 点击跳转到网站。 什么是命令行参数? 我们平时写的代码中写写到的主函数main函数是可以有参数的。 我们可以看一下这段代码的运行结果。 我们

    2024年01月18日
    浏览(45)
  • 【Linux】进程地址空间(带你认清内存的本质)

           🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️小林爱敲代码       🛰️博客专栏:✈️Linux之路       🛰️社区 :✈️ 进步学堂       🛰️欢迎关注:👍点赞🙌收藏✍️留言 我们在学习C语言的时候,应该都知道这

    2024年02月07日
    浏览(31)
  • 【Linux-14】进程地址空间&虚拟空间&页表——原理&知识点详解

    前言 大家好吖,欢迎来到 YY 滴 系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初学者易

    2024年04月29日
    浏览(44)
  • 【看表情包学Linux】进程地址空间 | 区域和页表 | 虚拟地址空间 | 初识写时拷贝

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 💭 写在前面: 本章核心主题为 \\\"进程地址空间\\\",会通过验证 Linux 进程的地址空间来开头,抛出 \\\"同一个值能有不同内容\\\" 的现象,通过该现象去推导出 \\\"虚拟地址\\\" 的概念。然后带着大家理解为什么虚拟地

    2024年01月20日
    浏览(57)
  • 吃透进程地址空间,理清OS内存管理机制

    Hello,大家好。本文要给大家带来的是有关Linux中的进程地址空间的讲解 首先我们来看着一张图,相信有学习过 C/C++内存管理 的同学一定可以清楚下面的这张图。知道内存中划分了很多的区域,包括 栈区、堆区、静态区、只读常量区、代码段、共享区等等 。 但是呢却不知道

    2024年02月08日
    浏览(42)
  • 【操作系统基础】【CPU访存原理】:寄存 缓存 内存 外存、内存空间分区、虚拟地址转换、虚拟地址的映射

    存储器怎么存储数据、内存空间分区、虚拟地址转换 计算机的存储器:寄存 缓存 内存 外存(按功能划分) 计算机的处理器需要一个存储器来存储大量的指令和数据以便自己不断取指执行和访问数据。 内存 (内存就是运行内存,如手机的8G运行内存,电脑的16G运行内存)就

    2024年01月25日
    浏览(53)
  • 【Linux】程序地址空间?进程地址空间

    了解进程的运行:  运行结果:我们会发现这打印的结果乱七八糟,因为它也不知道什么时候该干什么  我们让代码睡眠1秒:打印的结果就正常了  以前我们学习的内存管理(程序地址空间):  为了验证上面虚拟地址,我们运行下面代码: (这种问题出现的原因在下面的为

    2024年02月13日
    浏览(89)
  • Linux: 进程地址空间究竟是什么?进程地址空间存在意义何在?

     在C/C++中,我们常将内存分为: 代码区、常量区、全局区(静态区)、堆、栈 等等。相关内存区域划分如下:(X86, 32位平台) 如何验证C/C++中各区域的相对位置呢?  我们可以在每个区域中选择一个地址来验证C/C++中各区域的相对位置!!具体如下: 【源代码】: 【运行

    2024年04月08日
    浏览(69)
  • Linux 内核学习 3 - 虚拟内存和物理内存

    虚拟内存其实是 CPU 和操作系统使用的一个障眼法,联手给进程编织了一个假象,让进程误以为自己独占了全部的内存空间 : 在 32 位系统中,进程以为自己独占了 3G 的内存空间。 在 64 位系统中,进程以为自己独占了 128T 的内存空间。 这么做的好处是,操作系统为每个进程

    2024年01月21日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包