网站公司做网站修改会收费吗,wordpress 中文模版,上海市人力资源网官网,网站建设 租赁文章目录1 地址分布实际使用中的内存区域2 进程的虚拟地址描述用户空间mmap线程之间共享内存地址的实现机制1 地址分布 现在采用虚拟内存的操作系统通常都使用平坦地址空间#xff0c;平坦地址空间是指地址空间范围是一个独立的连续空间#xff08;比如#xff0c;地址从0扩…
文章目录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.hint 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 files 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_SIZEvm_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.hvoid *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域复制给子进程。