进程虚拟地址管理

文章目录

  • 1 地址分布
    • 实际使用中的内存区域
  • 2 进程的虚拟地址描述
    • 用户空间mmap
    • 线程之间共享内存地址的实现机制

1 地址分布

在这里插入图片描述
现在采用虚拟内存的操作系统通常都使用平坦地址空间,平坦地址空间是指地址空间范围是一个独立的连续空间(比如,地址从0扩展到429496729位地址空间),对于32位的操作系统而言,每个进程的虚拟地址空间都是0x00000000~0xC0000000,合计3G大小。

进程的3G虚拟地址空间只有映射为物理地址空间,才能够被使用,那么进程是如何管理和分配它的3G虚拟地址空间呢?
在这里插入图片描述
这就用到了分治思想,进程虚拟地址空间按照不同的访问属性和功能划分为不同的内存区域,我们也叫虚拟内存区域(VMA)。
内存区域可以包含各种内存对象,比如:

  • 代码段(text section):可执行文件的内存映射
  • 数据段:可执行文件的已初始化全局变量和静态局部变量的内存映射
  • bss段:未初始化的或者值为0的变量的内存映射
  • lib库的代码段:(多个)
  • lin库的数据段:(多个)
  • lib库的bss段:(多个)
  • 任何内存映射文件(有名mmap建立)
  • 任何共享内存段(匿名mmap建立)
  • 进程栈(stack)
  • 进程堆(heap)

实际使用中的内存区域

可以使用/proc文件系统和pmap工具查看给定进程的内存空间和其中所包含的内存区域。

#include <stdio.h>
#include <unistd.h>int main(void)
{printf("PID=%d\n",getpid());while(1){sleep(2);}return 0;
}

运行该程序,输入命令 cat /proc/<pid>/maps查看进程地址空间中的全部内存区域(我的机子是64位,所以使用的是64位虚拟地址空间)
在这里插入图片描述

进程的内存区域由vm_area_struct结构体描述,定义在文件linux/mm.h中

struct vm_area_struct {struct mm_struct * vm_mm;	/* The address space we belong to. */unsigned long vm_start;		/* Our start address within vm_mm. */unsigned long vm_end;		/* The first byte after our end addresswithin vm_mm. *//* linked list of VM areas per task, sorted by address */struct vm_area_struct *vm_next;pgprot_t vm_page_prot;		/* Access permissions of this VMA. */unsigned long vm_flags;		/* Flags, listed below. */struct rb_node vm_rb;/** For areas with an address space and backing store,* linkage into the address_space->i_mmap prio tree, or* linkage to the list of like vmas hanging off its node, or* linkage of vma in the address_space->i_mmap_nonlinear list.*/union {struct {struct list_head list;void *parent;	/* aligns with prio_tree_node parent */struct vm_area_struct *head;} vm_set;struct prio_tree_node prio_tree_node;} shared;/** A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma* list, after a COW of one of the file pages.  A MAP_SHARED vma* can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack* or brk vma (with NULL file) can only be in an anon_vma list.*/struct list_head anon_vma_node;	/* Serialized by anon_vma->lock */struct anon_vma *anon_vma;	/* Serialized by page_table_lock *//* Function pointers to deal with this struct. */struct vm_operations_struct * vm_ops;/* Information about our backing store: */unsigned long vm_pgoff;		/* Offset (within vm_file) in PAGE_SIZEunits, *not* PAGE_CACHE_SIZE */struct file * vm_file;		/* File we map to (can be NULL). */void * vm_private_data;		/* was vm_pte (shared mem) */#ifdef CONFIG_NUMAstruct mempolicy *vm_policy;	/* NUMA policy for the VMA */
#endif
};

上面的图片中,输出由六列,每一列都是vm_area_struct的一项

内核vm_area_struct中的项/proc/pid/maps中的项及其含义
vm_start第一列’-'前的数字,如55c4b4d68000 ,表示该虚拟内存区域的开始地址
vm_end第一列’-'后的数字 ,如55c4b4d69000 ,表示该虚拟内存区域的结束地址
vm_flags第二列,如r-xp,表示该虚拟内存区域的属性,每种属性用一个字段表示,r表示可读,w表示可写,x表示可执行,p和s共用一个字段,p表示私有段,s表示共享段,如果没有相应权限,用’-'代替
vm_pgoff第三列,如00001000,含义:对用有名映射,表示此虚拟内存起始地址在文件中以页为单位的编译,对匿名映射,它等于0或者vm_start/PAGE_SIZE
vm_file->f_dentry->d_inode->i_sb->s_dev第四列,如08:01,表示映射文件所属设备号,对匿名映射来说,因为没有文件在磁盘上,所有没有设备号,始终为00:00,对有名映射来说,是映射的文件所在设备的设备号
vm_file->f_dentry->d_inode->i_ino第五列,如1724853,含义:映射文件所属节点号,对匿名文件来说,因为没有节点号,所以时钟是0,对有名映射来说,是映射文件的结点号
第六列,如/lib/x86_64-linux-gnu/libc-2.27.so,对有名映射来说,是映射的文件名,对匿名映射来说,是此段虚拟内存在进程中的角色,stack表示在进程中作为栈使用,heap表示堆

2 进程的虚拟地址描述

内核使用mm_struct来描述一个进程的地址空间,进程的地址空间由多个VMA组成,下面列举几个mm_struct管理内存的几个重要域:

struct mm_struct {.../* 指向虚拟内存区域的链表 */struct vm_area_struct * mmap;		/* list of VMAs *//* 指向最近找到的虚拟内存区域 */struct vm_area_struct * mmap_cache;	/* last find_vma result *//* 指向该进程的页目录表 */pgd_t * pgd;...
};

VMA用struct vm_area_struct描述,内核将每个内存区域作为一个单独的内存对象管理,每个内存区域都有一致的属性,比如权限等。所以我们程序的代码段、数据段和bss段在内核里都分别有一个struct vm_area_struct结构体来描述。

在这里插入图片描述
进程由结构体task_struct描述,task_struct里面的mm域用来管理进程的内存,它指向mm_struct结构体,mm_struct的mmap域指向VMA链表,用来管理进程虚拟内存,虚拟内存地址又通过页表转换为物理地址,怎么转换的,由mm_struct的pgd页目录表来转换,从页目录表中找到物理地址。

用户空间mmap

 #include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);int munmap(void *addr, size_t length);

在用户空间使用mmap就是给进程添加一个虚拟内存区域,即在VMA链表中添加一个vm_area_struct结构

线程之间共享内存地址的实现机制

在Linux中,如果clone()时设备CLONE_VM标志,我们把这样的进程称作为线程,线程之间共享同样的虚拟内存空间。即将父进程的mm域复制给子进程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java两个文件夹比较路径_比较Java中两个文件的路径

java两个文件夹比较路径Given the paths of the two files and we have two compare the paths of the files in Java. 给定两个文件的路径&#xff0c;我们有两个比较Java中文件的路径。 Comparing paths of two files 比较两个文件的路径 To compare the paths of two file…

标题:加法变乘法

标题&#xff1a;我们都知道&#xff1a;123 … 49 1225 现在要求你把其中两个不相邻的加号变成乘号&#xff0c;使得结果为2015 比如&#xff1a; 123…10*1112…27*2829…49 2015 就是符合要求的答案。 请你寻找另外一个可能的答案&#xff0c;并把位置靠前的那个乘号左…

C# winform对话框用法大全收藏

对话框中我们常用了以下几种&#xff1a; 1、文件对话框(FileDialog) 它又常用到两个&#xff1a; 打开文件对话框(OpenFileDialog) 保存文件对话(SaveFileDialog) 2、字体对话框(FontDialog) 3、颜色对话框(&#xff23;olorDialog) 4、打印预浏对话框(PrintPreviewDialog) 5、…

【翻译】eXpressAppFramework QuickStart 业务模型设计(四)—— 实现自定义业务类...

这一讲&#xff0c;你将学到如何从头开始实现业务类。为此&#xff0c;将要实现Department和Position业务类。这些类将被应用到之前实现的Contact类中。你将学到引用对象自动生成用户界面的基本要素。 在此之前&#xff0c;我建议你去阅读一下 【翻译】eXpressAppFramework Qui…

内存重映射

文章目录1 kmap2 映射内核内存到用户空间使用remap_pfn_range使用io_remap_pfn_rangemmap文件操作建立VMA和实际物理地址的映射mmap 之前分配 一次性映射mmap 之前分配 Page FaultPage Fault 中分配 映射内核内存有时需要重新映射&#xff0c;无论是从内核到用户空间还是从内…

math.sqrt 有问题_JavaScript中带有示例的Math.sqrt()方法

math.sqrt 有问题JavaScript | Math.sqrt()方法 (JavaScript | Math.sqrt() Method) The Math.sqrt() method is inbuilt in JavaScript to find the square root of a number. In this tutorial, we will learn about the sqrt() method with examples. JavaScript中内置了Mat…

标题:移动距离

标题&#xff1a;移动距离 X星球居民小区的楼房全是一样的&#xff0c;并且按矩阵样式排列。其楼房的编号为1,2,3… 当排满一行时&#xff0c;从下一行相邻的楼往反方向排号。 比如&#xff1a;当小区排号宽度为6时&#xff0c;开始情形如下&#xff1a; 1 2 3 4 5 6 12 11 1…

ISAPI Rewrite 实现简单url重写、二级域名重写

实现步骤&#xff1a; 第一步&#xff1a;下载ISAPI_Rewrite.rar&#xff0c;将Rewrite文件夹和httpd.ini直接放在项目根目录下面。 第二步&#xff1a;IIS配置&#xff0c;筛选Rewrite文件夹里面的Rewrite.dll文件&#xff0c;如图&#xff1a; 第三步&#xff1a;在httpd.ini…

用户登录

用户登录 代码namespace 用户登录 {public partial class Form1 : Form{public Form1(){InitializeComponent();}bool b1, b2, b3, b4, b5, b6;private void button1_Click(object sender, EventArgs e){try{if (b1 && b2 && b3 && b4 && b5 &…

进程上下文和中断上下文

文章目录进程的preempt_count变量thread_infopreempt_counthardirq相关softirq相关上下文原文链接&#xff1a; https://zhuanlan.zhihu.com/p/88883239进程的preempt_count变量 thread_info 在内核中&#xff0c;上下文的设置和判断接口可以参考 include/linux/preempt.h 文…

标题:凑算式

标题&#xff1a;凑算式 这个算式中AI代表19的数字&#xff0c;不同的字母代表不同的数字。 比如&#xff1a; 68/3952/714 就是一种解法&#xff0c; 53/1972/486 是另一种解法。 这个算式一共有多少种解法&#xff1f; 注意&#xff1a;你提交应该是个整数&#xff0c;不要…

汇编中imul_JavaScript中带有示例的Math.imul()方法

汇编中imulJavaScript | Math.imul()方法 (JavaScript | Math.imul() Method) Math.imul() is a function in math library of JavaScript that is used to the 32-bit multiplication of the two values passed to it. It uses C-like semantics to find the multiplication. …

AFTER触发器与INSTEAD OF触发器的区别

INSTEAD OF 触发器用来代替通常的触发动作&#xff0c;即当对表进行INSERT、UPDATE 或 DELETE 操作时&#xff0c;系统不是直接对表执行这些操作&#xff0c;而是把操作内容交给触发器&#xff0c;让触发器检查所进行的操作是否正确。如正确才进行相应的操作。因此&#xff0c;…

Linux内存地址管理

文章目录系统内存布局内核地址的低端和高端内存概念低端内存高端内存地址转换和MMULinux中的四级分页模型虚拟地址字段页表处理将虚拟地址转换物理地址Linux系统中的每个内存地址都是虚拟的&#xff0c;它们不直接指向任何物理内存地址。每当访问内存位置时&#xff0c;可以执行…

录制caf 转 mp3

编译需要使用的 lame库http://www.cocoachina.com/bbs/read.php?tid108237参考的文章http://blog.csdn.net/ysy441088327/article/details/7392842说起来&#xff0c;我一直在找一个音频转换成mp3的方法。一年前&#xff0c;我成功编译出了一个lame for armv7的库。苦于不会使…

杭电2012-素数判定(C)

Problem Description 对于表达式n^2n41&#xff0c;当n在&#xff08;x,y&#xff09;范围内取整数值时&#xff08;包括x,y&#xff09;(-39<x<y<50)&#xff0c;判定该表达式的值是否都为素数。 Input 输入数据有多组&#xff0c;每组占一行&#xff0c;由两个整数…

math.ceil带小数点_JavaScript中带有示例的Math.ceil()方法

math.ceil带小数点JavaScript | Math.ceil()方法 (JavaScript | Math.ceil() Method) Math.ceil() is a function in math library of JavaScript that is used to round up the number passed to the function. The method will return the nearest integer value indeed is g…

開發記要 詭異的變量

告別繁體文盲,從寫blog開始 Variable命名很重要,有多重要,看看.net和java的加密就知道, 都是把variable改到一塌糊塗,你想看看都沒門. 但是這幾天看遺留系統的代碼,真是大開眼界。 我一直以為別人寫a,b,c,d這些單字節variable已經很過分。直到我看到以下這幾個&#xff0…

排序算法---快速排序、堆排序、冒泡排序

排序算法1 快速排序代码实现stdlib库快排2 堆排序堆排序的基本思想如何构造一个大顶堆排序3 冒泡排序1 快速排序 文章原地址&#xff1a;https://blog.csdn.net/morewindows/article/details/6684558 快速排序的平均时间复杂度是0(NlogN)&#xff0c;它采用了一种分治的策略&a…

CSS Hack 汇总快查

*:lang(zh) select {font:12px !important;} /*FF的专用*/ select:empty {font:12px !important;} /*safari可见*/ 这里select是选择符&#xff0c;根据情况更换。第二句是MAC上safari浏览器独有的。 仅IE7识别 *html {…} 当面临需要只针对IE7做样式的时候就可以采用这个HACK…