0
点赞
收藏
分享

微信扫一扫

配置dns主从服务器,能够实现正常的正反向解析

晒大太阳了 2024-01-20 阅读 12

文章目录

C语言地址空间回顾

我们在讲C语言的时候,老师给大家画过这样的空间布局图
请添加图片描述

C/C++内存分布简图:

+------------------+     高地址
|                  |
|       栈         | <- 本地变量,函数调用信息等
|                  |
+------------------+
|                  |
|       堆         | <- 动态分配的变量(malloc/new)
|                  |
+------------------+
|                  |
|   未初始化数据段   |
|    (BSS 段)     | <- 未初始化的静态和全局变量
|                  |
+------------------+
|                  |
|   已初始化数据段    | <- 已初始化的静态和全局变量
|     (数据段)      |
|                  |
+------------------+
|                  |
|    常量数据段      | <- 字面量,常量字符串等
|                  |
+------------------+
|                  |
|      代码段       | <- 程序代码(虚函数和普通函数)
|                  |
+------------------+     低地址

进程地址空间概念

实际上操作系统会给每一个进程都创建一个独立的虚拟地址空间,然后通过页表将虚拟地址空间与物理内存一一对应 (映射),我们用户只能得到虚拟地址空间中的虚拟地址,当我们修改虚拟地址中的数据时,操作系统会先通过页表找到对应的物理内存,然后修改物理内存中的数据。
请添加图片描述

Linux是如何管理每个进程的地址空间?

所以,和管理进程一样,操作系统会使用一种内核数据结构来对地址空间进行管理,Linux中用于 管理地址空间的内核数据结构叫做 mm_struct,操作系统会为每个进程创建一个 mm_struct 对象,然后通过管理结构体对象来间接管理进程地址空间。
请添加图片描述

查看mm_struct的定义:

struct mm_struct 
{
	// ...
    unsigned long total_vm, locked_vm, shared_vm, exec_vm;
    unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
    unsigned long start_code, end_code, start_data, end_data;
    unsigned long start_brk, brk, start_stack;
    unsigned long arg_start, arg_end, env_start, env_end;
    // ...
};
  • total_vm:可能表示虚拟内存的总量。
  • locked_vm:可能表示被锁定,不能被换出的虚拟内存的数量。
  • shared_vm:可能表示被多个进程共享的虚拟内存的数量。
  • exec_vm:可能表示可执行的虚拟内存的数量。
  • stack_vm:可能表示栈内存的虚拟内存的数量。
  • reserved_vm:可能表示已预留但尚未使用的虚拟内存的数量。
  • def_flags:可能表示默认的内存区域标志。
  • nr_ptes:可能表示页表条目的数量。
  • start_codeend_code:可能表示代码段的开始和结束位置。
  • start_dataend_data:可能表示数据段的开始和结束位置。
  • start_brkbrk:可能表示堆的开始位置和当前位置。
  • start_stack:可能表示栈的开始位置。
  • arg_startarg_end:可能表示命令行参数的开始和结束位置。
  • env_startenv_end:可能表示环境变量的开始和结束位置。

可以看到,进程地址空间其实也是进程属性的一种,我们可以通过进程的 task_struct 来找到/管理进程对应的地址空间。

为什么要有进程地址空间和页表?

  • 因为有了进程地址空间和页表,物理内存空间上不连续、无序的空间就可以通过页表这一映射关系联系在一起,让进程以统一的视角看待内存。
  • 有了进程地址空间和页表后,每个进程都认为自己在独占内存,这样能更好的保障进程的独立性以及合理使用内存空间(当实际需要使用内存空间的时候再在内存进行开辟),并能将进程管理与内存管理进行解耦合。
  • 地址空间+页表的设计是保护内存安全的重要手段!

页表的细节

页表其实不光存放虚拟地址和物理内存地址,还有其他的属性,比如会存放权限属性。
请添加图片描述

举报

相关推荐

0 条评论