目录
/proc/<pid>/maps
背景
相对于/proc/meminfo和dumpsys meminfo可以看到系统整体的内存信息,我们还需要能够具体到每一个进程内存占用统计的信息。
在分析内存问题的时候,会经常依赖kernel的proc文件系统下各个进程的文件节点,从中获取当前进程的详细内存信息,今天就来简单介绍一下比较常用的一个节点/proc/pid/maps
Proc/pid/maps显示进程映射了的内存区域和访问权限。对应内核中的操作集为proc_pid_maps_op,具体的导出函数为:show_map
内核中进程的一段地址空间用一个vm_area_struct结构体表示,所有地址空间存储在 :struct task_struct -> struct mm_struct -> mmap链表中。
具体描述
如下为一个vm_area_struct结构体的描述,详解描述了一个虚拟内存区域的信息。
vm_area_struct
struct vm_area_struct {
/* The first cache line has the info for VMA tree walking. */
unsigned long vm_start; /* Our start address within vm_mm. */ //区域的首地址
unsigned long vm_end; /* The first byte after our end address within vm_mm. */ //区域的尾地址
/* linked list of VM areas per task, sorted by address */
//该vma在一个进程的vma链表中的前驱vma和后驱vma指针,链表中的vma都是按地址来排序的
struct vm_area_struct *vm_next, *vm_prev; //vma表,下一个vma;vma表,上一个vma
struct rb_node vm_rb; //红黑树中对应的节点
/*
* Largest free memory gap in bytes to the left of this VMA.
* Either between this VMA and vma->vm_prev, or between one of the
* VMAs below us in the VMA rbtree and its ->vm_prev. This helps
* get_unmapped_area find a free area of the right size.
*/
unsigned long rb_subtree_gap;
/* Second cache line starts here. */
struct mm_struct *vm_mm; /* The address space we belong to. */ // 所属的内存描述符,vma属于哪个mm_struct
pgprot_t vm_page_prot; /* Access permissions of this VMA. */ //vma的访问权限
unsigned long vm_flags; /* Flags, see mm.h. */
/*
* For areas with an address space and backing store,
* linkage into the address_space->i_mmap interval tree.
*
* For private anonymous mappings, a pointer to a null terminated string
* in the user process containing the name given to the vma, or NULL
* if unnamed.
*/
//shared联合体用于和address space关联
union {
struct {
struct rb_node rb;
unsigned long rb_subtree_last;
} shared;
const char __user *anon_name;
};
/*
* 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.
*/
/*anno_vma_chain和annon_vma用于管理源自匿名映射的共享页*/
struct list_head anon_vma_chain; /* Serialized by mmap_sem &
* page_table_lock */
struct anon_vma *anon_vma; /* Serialized by page_table_lock */ //指向匿名域的指针
/*该vma上的各种标准操作函数指针集*/
const struct vm_operations_struct *vm_ops;
/* Information about our backing store: */
unsigned long vm_pgoff; /* 映射文件的偏移量,以PAGE_SIZE为单位 */
struct file * vm_file; /* 映射的文件,没有则为NULL;可以通过这个区分匿名页和文件页*/
void * vm_private_data; /* was vm_pte (shared mem) */
#ifdef CONFIG_SWAP
atomic_long_t swap_readahead_info;
#endif
#ifndef CONFIG_MMU
struct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
seqcount_t vm_sequence;
atomic_t vm_ref_count; /* see vma_get(), vma_put() */
#endif
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
ANDROID_KABI_RESERVE(3);
ANDROID_KABI_RESERVE(4);
ANDROID_VENDOR_DATA(1);
} __randomize_lay