Linux-程序地址空间

目录

 1. 程序地址空间分布

2. 两个问题

3. 虚拟地址和物理地址

4. 页表

5. 解决问题

6. 为什么要有地址空间


 1. 程序地址空间分布

测试一下: 

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

int gal_init = 1;
int gal_uninit;


int main(int argc, char* argv[], char* env[])
{
    printf("code add:%p\n",main);
    const char* str = "hello";
    
    printf("str add:%p\n",str);
    printf("init global add:%p\n",&gal_init);
    printf("uninit global add:%p\n",&gal_uninit);
    char* heap1 = (char*)malloc(10);
    char* heap2 = (char*)malloc(10);
    char* heap3 = (char*)malloc(10);
    char* heap4 = (char*)malloc(10);
    
    printf("heap1 add:%p\n",heap1);
    printf("heap2 add:%p\n",heap2);
    printf("heap3 add:%p\n",heap3);
    printf("heap4 add:%p\n",heap4);

    printf("stack1 add:%p\n",&heap1);
    printf("stack2 add:%p\n",&heap2);
    printf("stack3 add:%p\n",&heap3);
    printf("stack4 add:%p\n",&heap4);


    int i = 0;
    for(;i < argc; ++i)
    {
        printf("%s:%p\n",argv[i],&argv[i]);
    }
    printf("env add:%p\n",env);
    return 0;
}

运行结果:

code add0x40057d
int a add0x7ffc2b16df7c
static int b add0x601044
str add0x40081d
init global add0x60103c
uninit global add0x601048
heap1 add0x2301010
heap2 add0x2301030
heap3 add0x2301050
heap4 add0x2301070
stack1 add0x7ffc2b16df70
stack2 add0x7ffc2b16df68
stack3 add0x7ffc2b16df60
stack4 add0x7ffc2b16df58
./myproc0x7ffc2b16e078
env add0x7ffc2b16e088

这些都是之前就了解过的内容,今天详细聊聊地址空间

2. 两个问题

1. 安全问题:

这些程序都在同一个地址空间中,如果发生了越界访问,野指针问题,这些问题该怎么办?

2. 一个特殊现象问题:

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

int main()
{
    int num = 0;
    int ret = fork();
    if(ret == 0)
    {
        int i = 3;
        while(i--)
        {
            printf("I am child,num = %d,&num = %p\n",num,&num);
            sleep(1);                
        }
        num = 1;
        while(1)
        {
            printf("I am child,num = %d,&num = %p\n",num,&num);
            sleep(1);
        }
    }
    else
    {
        while(1)
        {
            printf("I am father,num = %d,&num = %p\n",num,&num);
            sleep(1);
        }
    }
    return 0;
}

为什么父进程和子进程中的num同一个地址,但是却有两个值?

3. 虚拟地址和物理地址

在Linux地址下,这种地址叫做 虚拟地址

我们在用C/C++语言所看到的地址,全部都是虚拟地址!

物理地址,用户一概看不到,由OS统一管理

由OS负责将 虚拟地址 转化成 物理地址 

上面的地址空间分布就是虚拟地址,每个进程被创建,就会有对应的虚拟地址表

虚拟地址表在linux下就是由mm_struct结构体来描述的

Linux下的进程管理PCB:task_struct就有一个指针指向mm_struct,程序和虚拟地址空间联系起来了

4. 页表

OS是如何把虚拟地址转换成物理地址的呢?

页表

页表是一种key-value的数据结构,记录虚拟地址和物理地址一一映射关系

task_struck有一个指针指向页表

页表里的值(虚拟地址,物理地址)是哪里来的呢?

代码在被编译器编译后的每一条语句每一个函数都会有对应的地址,这个地址是逻辑地址,和虚拟地址一样,作为页表的虚拟地址。当程序被加载到物理内存中时,就会有对应的物理地址,然后在对应到页表里面。

程序被执行时,使用的地址是虚拟地址,需要用页表映射到物理地址 

5. 解决问题

到这里,我们就可以解决第一个问题,每个进程都有一个虚拟地址和页表,这些都由OS来维护,在页表对应的每一个物理地址后面,都有一个像文件访问权限一样的标志,如果这个物理地址没有访问权限,就会直接报错终止。有效的保护了物理内存。

第二问题的答案就在图中,fork函数创建子进程时,其实就是拷贝了大部分对应的task_struct,mm_struct和页表,因为父子进程之间大部分属性都一样,但当需要改变num的值时,子进程就在物理空间上重新开了一块空间,拷贝父进程,OS也会更新对应的页表映射关系。这个叫做写时拷贝。但是虚拟地址还是一样的,只是映射关系发生了变化。所以num相同的虚拟地址,不同的值。

6. 为什么要有地址空间

安全性,有效的保护了物理内存

因为地址空间和页表是OS创建并维护的,凡是想用地址空间和页表进行映射,都需要在OS的监管下来进行访问。

内存管理模块和进程管理模块完成了解耦

提高内存的利用率

用户申请的物理空间,malloc和new其实是在虚拟地址上申请的,OS通过延迟分配,提高物理内存的利用率

地址空间和页表的存在可以将内存分布有序化(按照地址空间分布)和进程的独立性(不同的进程映射到不同的物理空间)每一个进程不知道其他进程的存在

对于程序的分批加载,当程序刚刚新建的状态下,进程就只创建内核结构,程序和数据还没有加载到内存中。

程序的分批换出,当进程短时间内不会再被执行了,比如阻塞了,进程的数据和代码被换出到磁盘中的swap区,页表的映射关系也改为磁盘地址。这个过程就叫挂起。

完,写的不好的地方多有体谅,还在学

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/516057.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#仿OutLook的特色窗体设计

目录 1. 资源图片准备 2. 设计流程&#xff1a; &#xff08;1&#xff09;用MenuStrip控件设计菜单栏 &#xff08;2&#xff09;用ToolStrip控件设计工具栏 &#xff08;3&#xff09;用StatusStrip控件设计状态栏 &#xff08;4&#xff09;ImageList组件装载树节点图…

小米手机刷入Root权限

小米手机刷入Root权限 解Bi锁下载刷机包刷入Root准备工作开始刷入 验证root 解Bi锁 下载地址&#xff1a;小米BI官方解锁工具需要先申请&#xff0c;申请通过才能解锁注意&#xff1a;解BI锁会清除所有数据。 下载刷机包 根据自己的手机型号和版本到小米官网下载和自己手机版…

android framework 学习笔记(1)

学习资料&#xff1a;《Android Framework 开发揭秘》_哔哩哔哩_bilibili 什么是android framework 看图说话&#xff0c;android框架从上至下分为&#xff1a; 应用层(Application)&#xff0c;Java framework(Application Framework),Native framework. 包括Libraries 和 A…

基于JSP杏种质资源管理系统

摘要 社会的进步导致人们对于学习的追求永不止境&#xff0c;那么追求农业信息化的方式也从单一的田地教程变成了多样化的学习方式。多样化的学习方式不仅仅是需要人们智慧的依靠&#xff0c;还需要能够通过软件的加持进行信息化的价值体现。软件和系统的产生&#xff0c;从表…

【mT5模型】mT5: A Massively Multilingual Pre-trained Text-to-Text Transformer

【mT5模型】mT5: A Massively Multilingual Pre-trained Text-to-Text Transformer 论文信息 阅读评价 Abstract Introduction Background on T5 and C4 mC4 and mT5 mC4 mT5 Comparison to related models Experiments Zero-shot generation Illegal predictions Pre…

【Pyhton中requests库、re库、文件读写的了解】

1、requests库&#xff1a;第三方库&#xff0c;主要用于Python发送HTTP请求 response1 requests.get(https://www.qq.com/) # 发送get请求 # requestdata {User-Agen: KWHJJKLK, Accept: text/html, Cookie: sjdshkwje213} # 请求数据 # response2 requests.post(https:…

C++(13): 智能指针shared_ptr

1. 概述 shared_ptr智能指针&#xff0c;本质是“离开作用域会自动调整(减小)引用计数&#xff0c;如果引用计数为0&#xff0c;则会调用析构函数”。这样一来&#xff0c;就进化成类似于int、float等的一种会被自动释放的类型。 2. 初始化智能指针 初始化一个智能指针的方式比…

基于springboot实现房屋租赁管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁系统演示 摘要 房屋是人类生活栖息的重要场所&#xff0c;随着城市中的流动人口的增多&#xff0c;人们对房屋租赁需求越来越高&#xff0c;为满足用户查询房屋、预约看房、房屋租赁的需求&#xff0c;特开发了本基于Spring Boot的房屋租赁系统。 …

python怎么存储数据

在Python开发中&#xff0c;数据存储、读取是必不可少的环节&#xff0c;而且可以采用的存储方式也很多&#xff0c;常用的方法有json文件、csv文件、MySQL数据库、Redis数据库以及Mongdb数据库等。 1. json文件存储数据 json是一种轻量级的数据交换格式&#xff0c;采用完全…

FreeRTOS第四天

1.总结二进制信号量和计数型信号量的区别&#xff0c;以及他们的使用场景。 进制信号量&#xff1a;信号量的数值只有0和1。(用于共享资源的访问&#xff09; 计数型信号量: 计数型信号量的值一般是大于或者等于2 (生产者和消费者模型) 2.使用技术型信号量完成生产者和消费者模…

掌握 Go 语言的 defer 关键字

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等&#xff0c;您的关注将是我的更新动力&#xff01; 在 Go 语言编程中&#xff0c;文件的输入/输出是一个常见的操作。我们知道&#xff0c;每次打开文件后&#xff0c;都需要在操作…

在Linux系统上搭建Android、Linux和Chrome性能监控和Trace分析的系统

perfetto是知名的Android系统性能分析平台。我们还可以用它去分析Linux系统和Chrome&#xff08;需要装扩展&#xff09;。本文我们只介绍如何安装的验证。 部署 我们使用Docker部署perfetto ui系统。 FROM ubuntu:20.04 WORKDIR /perfetto-ui RUN apt-get update -y RUN ap…

蓝桥集训之阶乘分解

蓝桥集训之阶乘分解 核心思想&#xff1a;线性筛质数 筛出每一个质数后 只要将所有质数的1 2 3 … 次方个数都加上即可 #include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N 1e610;int …

MySQL 数据学习笔记速查表(视图、存储过程、事务)

文章目录 十三、视图1、视图是什么&#xff1f;2、视图的特性&#xff1f;3、视图的作用&#xff1f;4、视图的用途&#xff1f;5、视图的使用&#xff1f;1、基本语法2、创建视图3、调用视图4、视图练习(1) 利用试图简化复杂的联结(2) 利用视图重新格式化检索出的数据(3) 利用…

本地Windows打包启动前端后台

本地Windows打包启动前端后台 1、安装jdk Windows JDK安装 2、Nginx 2.1、将 nginx-1.16.1文件夹复制到D:\home\jisapp目录下 2.2、域名证书配置&#xff1a; 将域名证书放到D:\home\jisapp\ssl\2023目录下->配置nginx.conf文件&#xff08;D:\home\jisapp\nginx-1.22.0…

vconsole助力实现在线代码编辑调试

概述 前面有文章monaco-editor做自己的代码测试工具 &#xff0c;本文书接前文&#xff0c;在代码中加入vconsole工具&#xff0c;可以进行代码调试、查看网络、查看元素等。 效果 vconsole简介 vconsole是一个轻量、可拓展、针对手机网页的前端开发者调试面板。跟框架无关的…

轮播图实现

基于html、js实现网页中常见的轮播图 html: <div id"box"><img src"./images/1.jpg" alt""><img src"./images/2.jpg" alt""><img src"./images/3.jpg" alt""><img src&q…

Minikube本地搭建单节点Kubernetes集群

1、什么是 Minikube Minikube 是一个开源工具&#xff0c;旨在为开发者提供一种便捷的方式在本地环境中搭建单节点的 Kubernetes 集群。它主要用于开发、测试和学习 Kubernetes 应用程序&#xff0c;无需依赖大型的硬件资源或复杂的多节点集群配置。minikube 使用轻量级虚拟化技…

CountDownTimer 倒计时不准确问题解决

前言 最近笔者在实现一共和倒计时有关的功能&#xff0c;使用CountDownTimer实现。然而&#xff0c;在测试的时候发现&#xff0c;倒计时经常发现跳秒、不出现1的情况&#xff0c;因此对这方面进行了一些了解。本文准备介绍一下CountDownTimer倒计时不准确的原因&#xff0c;以…

【进阶六】Python实现SDVRPTW常见求解算法——遗传算法(GA)

基于python语言&#xff0c;采用经典遗传算法&#xff08;GA&#xff09;对 带硬时间窗的需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整2.1 需求拆分2.2 需求拆分后的服务时长取值问题 3. 求解结果4. 代码片段参…