进程如何管理和分配虚拟地址空间的?

分治思想

内核通过mm_struct来描述一个进程的虚拟地址空间,按照不同的属性和功能对虚拟内存进行划分,划分为一个个VMA

  • 代码段.text
  • 数据段.data
  • bss
  • lib库的代码段
  • lib库的数据段
  • lib库的bss
  • 任何内存映射文件(有名mmap建立)
  • 任何共享内存段(匿名mmap建立)
  • 进程栈stack
  • 进程堆heap
    image

image
image
在linux系统上通过cat /proc/pid/maps命令查看虚拟内存结构:
image
每一列的含义分别为
image
实际的结构:

mm_struct
  398 struct mm_struct {
  399   struct vm_area_struct * mmap;   /* list of VMAs */    //虚拟地址空间结构体,双向链表包含红黑树节点访问到不能访问的区域。
  400   struct rb_root mm_rb;                                 //红黑树的根节点
  401   struct vm_area_struct * mmap_cache; /* last find_vma result */  //mmap的高速缓冲器,指的是mmap最后指向的一个虚拟地址区间
  402 #ifdef CONFIG_MMU
  403   unsigned long (*get_unmapped_area) (struct file *filp,
  404         unsigned long addr, unsigned long len,
  405         unsigned long pgoff, unsigned long flags);
  406   void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
  407 #endif
  408   unsigned long mmap_base;    /* base of mmap area */                                       //mmap区域的基地址
  409   unsigned long mmap_legacy_base;         /* base of mmap area in bottom-up allocations */  //自底向上的配置
  410   unsigned long task_size;    /* size of task vm space */                                   //进程的虚拟地址空间大小
  411   unsigned long cached_hole_size;   /* if non-zero, the largest hole below free_area_cache */ //缓冲器的最大的大小
  412   unsigned long free_area_cache;    /* first hole of size cached_hole_size or larger */       //不受约束的空间大小
  413   unsigned long highest_vm_end;   /* highest vma end address */                             //虚拟地址空间最大结尾地址
  414   pgd_t * pgd;                                                                              //页表的全局目录
  415   atomic_t mm_users;      /* How many users with user space? */                             //有多少用户
  416   atomic_t mm_count;      /* How many references to "struct mm_struct" (users count as 1) */ //有多少用户引用mm_struct
  417   atomic_long_t nr_ptes;  /* Page table pages */                                       //页表
  418   int map_count;        /* number of VMAs */                                               //虚拟地址空间的个数
  419 
  420   spinlock_t page_table_lock;   /* Protects page tables and some counters */               //保护页表和用户
  421   struct rw_semaphore mmap_sem;                                                            //读写信号
  422 
  423   struct list_head mmlist;    /* List of maybe swapped mm's.  These are globally strung
  424              * together off init_mm.mmlist, and are protected
  425              * by mmlist_lock
  426              */
  427 
  428 
  429   unsigned long hiwater_rss;  /* High-watermark of RSS usage */                     //标志
  430   unsigned long hiwater_vm; /* High-water virtual memory usage */
  431 
  432   unsigned long total_vm;   /* Total pages mapped */
  433   unsigned long locked_vm;  /* Pages that have PG_mlocked set */
  434   unsigned long pinned_vm;  /* Refcount permanently increased */
  435   unsigned long shared_vm;  /* Shared pages (files) */
  436   unsigned long exec_vm;    /* VM_EXEC & ~VM_WRITE */
  437   unsigned long stack_vm;   /* VM_GROWSUP/DOWN */
  438   unsigned long def_flags;
  439   unsigned long start_code, end_code, start_data, end_data;               //开始代码段,结束代码。开始数据,结束数据
  440   unsigned long start_brk, brk, start_stack;                              //堆的开始和结束。
  441   unsigned long arg_start, arg_end, env_start, env_end;                   //参数的起始和结束,环境变量的起始和终点
  442 
  443   unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
        ...
};


vma
  281 struct vm_area_struct {
  282   /* The first cache line has the info for VMA tree walking. */    //第一个高速缓存行包含VMA树便利的信息
  283 
  284   unsigned long vm_start;   /* Our start address within vm_mm. */ //虚拟地址空间vm_mm起始地址
  285   unsigned long vm_end;   /* The first byte after our end address  
  286              within vm_mm. */                                     //在vm_mm中结束地址的第一个字节
  287 
  288   /* linked list of VM areas per task, sorted by address */       
  289   struct vm_area_struct *vm_next, *vm_prev;                       //双向链表连接以便于遍历
  290 
E>291   struct rb_node vm_rb;                                           //红黑树节点
  292 
  293   /*
  294    * Largest free memory gap in bytes to the left of this VMA.     //VMA左边最大的可用内存缺口
  295    * Either between this VMA and vma->vm_prev, or between one of the  
  296    * VMAs below us in the VMA rbtree and its ->vm_prev. This helps   //要么在当前的VMA和vma的前一个,要么是在VMA红黑树和它的前                                                                              一个中的VMAs之间
  297    * get_unmapped_area find a free area of the right size.        //这样有助于get_unmapped_area找到合适的空闲区域              
  298    */
  299   unsigned long rb_subtree_gap;                                  //红黑树子树的缺口
  300 
  301   /* Second cache line starts here. */
  302 
 302 
  303   struct mm_struct *vm_mm;  /* The address space we belong to. */   //进程拥有的地址空间
E>304   pgprot_t vm_page_prot;    /* Access permissions of this VMA. */   //此VMA访问权限
  305   unsigned long vm_flags;   /* Flags, see mm.h. */                  //标志
  306 
  307   /*
  308    * For areas with an address space and backing store,                                                                        
  309    * linkage into the address_space->i_mmap interval tree, or
  310    * linkage of vma in the address_space->i_mmap_nonlinear list.  //作为地址空间和后备存储区域,链接到间隔树或者链接到非线性链                                                                           表里的vma
  311    */
  312   union {
  313     struct {
  314       struct rb_node rb;
  315       unsigned long rb_subtree_last;
  316     } linear; //线性
  317     struct list_head nonlinear;  //链表非线性
  318   } shared;
  319 
  320   /*
  321    * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
  322    * list, after a COW of one of the file pages.  A MAP_SHARED vma
  323    * can only be in the i_mmap tree.  An anonymous MAP_PRIVATE, stack
  324    * or brk vma (with NULL file) can only be in an anon_vma list. //MAP_SHARED只能                           在i_mmap树。匿名的对象,栈或者堆只能存在链表                                                                           里
  325    */
  326   struct list_head anon_vma_chain; /* Serialized by mmap_sem &
  327             * page_table_lock */
  328   struct anon_vma *anon_vma;  /* Serialized by page_table_lock */
  329 
  330   /* Function pointers to deal with this struct. */
  331   const struct vm_operations_struct *vm_ops;               //虚拟内存
  332 
  333   /* Information about our backing store: */
  334   unsigned long vm_pgoff;   /* Offset (within vm_file) in PAGE_SIZE
  335              units, *not* PAGE_CACHE_SIZE */
  336   struct file * vm_file;    /* File we map to (can be NULL). */    //指向的文件
  337   void * vm_private_data;   /* was vm_pte (shared mem) */
  		...
  };

image

image
进程与线程

posted @   antidogmatist  阅读(31)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示