您的位置:首页 > 运维架构 > Linux

Linux之内存管理mm_struct

2017-04-15 12:07 441 查看
每个进程都有自己的mm_struct,使得每个进程都有自己独立的虚拟的地址空间

在每个进程的task_struct里都会有一个struct mm_struct*指向每个进程自己的mm_struct,mm_sruct是内存描述符,在每个mm_struct又都有一个pgd_t * 使其指向页表,然后通过页表实现从虚拟地址到物理地址的映射。

Linux虚拟地址用户空间分布



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 addr, unsigned long len,
unsigned long pgoff, 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 total_vm, locked_vm, shared_vm, exec_vm;
//total_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
};


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: