程序笔记   发布时间:2022-05-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Linux内存描述符mm_struct实例详解大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起。(所依据的代码是2.6.32.60)

无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context。其中有一个被称为'内存描述符‘(memory descriptor)的数据结构mm_struct,抽象并描述了linux视角下管理进程地址空间的所有信息。

@H_367_0@mm_struct定义在include/linux/mm_types.h中,其中的域抽象了进程的地址空间,如下图所示:

@H_801_6@

Linux内存描述符mm_struct实例详解

struct mm_struct {
  struct vm_area_struct * mmap;  //指向虚拟区间(VMA)的链表
  struct rb_root mm_rb;      //指向线性区对象红黑树的根
  struct vm_area_struct * mmap_cache;   //指向最近找到的虚拟区间
  unsigned long(*get_unmapped_area) (struct file *filp,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags);//在进程地址空间中搜索有效线性地址区
  unsigned long(*get_unmapped_exec_area) (struct file *filp,unsigned long flags);
  voID(*unmap_area) (struct mm_struct *mm,unsigned long addr);//释放线性地址区间时调用的方法
  unsigned long mmap_base;        /* base of mmap area */
  unsigned long task_size;        /* size of task vm space */
  unsigned long cached_hole_size;
  unsigned long free_area_cache;     //内核从这个地址开始搜索进程地址空间中线性地址的空闲区域
  pgd_t * pgd;              //指向页全局目录
  atomic_t mm_users;           //次使用计数器,使用这块空间的个数  
  atomic_t mm_count;           //主使用计数器
  int map_count;             //线性的个数
  struct rw_semaphore mmap_sem;      //线性区的读/写信号量
  spinlock_t page_table_lock;       //线性区的自旋锁和页表的自旋锁
  struct List_head mmList;       //指向内存描述符链表中的相邻元素
  /* Special counters,in some configurations protected by the
  * page_table_lock,in other configurations by being atomic.
  */
  mm_counter_t _file_RSS; //mm_counter_t代表的类型实际是typedef atomic_long_t
  mm_counter_t _anon_RSS; 
  mm_counter_t _swap_usage;
  unsigned long hiwater_RSS;  //进程所拥有的最大页框数
  unsigned long hiwater_vm;   //进程线性区中最大页数
  unsigned long @R_481_10586@l_vm,locked_vm,shared_vm,exec_vm;
  //@R_481_10586@l_vm 进程地址空间的大小(页数)
  //locked_vm 锁住而不能换出的页的个数
  //shared_vm 共享文件内存映射中的页数
  unsigned long stack_vm,reserved_vm,def_flags,nr_ptes;
  //stack_vm 用户堆栈中的页数
  //reserved_vm 在保留区中的页数或者在特殊线性区中的页数
  //def_flags 线性区默认的访问标志
  //nr_ptes 进程的页表数
  unsigned long start_code,end_code,start_data,end_data;
  //start_code 可执行代码的起始地址
  //end_code 可执行代码的最后地址
  //start_data已初始化数据的起始地址
  // end_data已初始化数据的最后地址
  unsigned long starT_Brk,brk,start_stack;
  //start_stack堆的起始位置
  //brk堆的当前的最后地址
  //用户堆栈的起始地址
  unsigned long arg_start,arg_end,env_start,env_end;
  //arg_start 命令行参数的起始地址
  //arg_end命令行参数的起始地址
  //env_start环境变量的起始地址
  //env_end环境变量的最后地址
  unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
  struct linux_binfmt *binfmt;
  cpumask_t cpu_vm_mask; //用于惰性TLB交换的位掩码
  /* Architecture-specific MM context */
  mm_context_t context; //指向有关特定结构体系信息的表
  unsigned int faultstamp;
  unsigned int token_priority;
  unsigned int last_interval;
  unsigned long flags; /* Must use atomic bitops to access the bits */
  struct core_state *core_state; /* coredumPing support */
#ifdef CONfig_AIO
  spinlock_t       ioctx_lock; //用于保护异步I/O上下文链表的锁
  struct hList_head    ioctx_List;//异步I/O上下文
#endif
#ifdef CONfig_MM_owneR
  struct task_struct *owner;
#endif
#ifdef CONfig_PROC_FS
  unsigned long num_exe_file_vmas;
#endif
#ifdef CONfig_MMU_NOTIFIER
  struct mmu_notifIEr_mm *mmu_notifIEr_mm;
#endif
#ifdef CONfig_transparent_HUGEPAGE
  pgtable_t pmd_huge_pte; /* protected by page_table_lock */
#endif
#ifdef __GENKSymS__
  unsigned long rh_reserved[2];
#else
  //有多少任务分享这个mm OOM_disABLE
  union {
    unsigned long rh_reserved_aux;
    atomic_t oom_disable_count;
  };
  /* base of lib map area (ASCII armour) */
  unsigned long shlib_base;
#endif
};
@H_801_6@

Linux内存描述符mm_struct实例详解


总结

以上所述是小编给大家介绍的linux内存描述符mm_struct实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

大佬总结

以上是大佬教程为你收集整理的Linux内存描述符mm_struct实例详解全部内容,希望文章能够帮你解决Linux内存描述符mm_struct实例详解所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。