基于msm-5.4
一、初探
1. 打印格式
# cat /proc/593/status Name: surfaceflinger ... VmPeak: 11322904 kB VmSize: 11306812 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 92828 kB VmRSS: 91100 kB RssAnon: 19708 kB RssFile: 70884 kB RssShmem: 508 kB VmData: 53808 kB VmStk: 132 kB VmExe: 5680 kB VmLib: 28768 kB VmPTE: 524 kB VmSwap: 0 kB CoreDumping: 0 THP_enabled: 0 ...
内容解释:
VmPeak: 虚拟内存占用峰值
VmSize: 当前虚拟内存占用量
VmLck: 锁定的虚拟内存量
VmPin: Pin住的内存量
VmHWM:
VmRSS: 进程当前在虚拟内存中占用的总空间,包括进程本身和所有链接库。
RssAnon: 进程当前在虚拟内存中匿名页占用的内存量
RssFile: 进程当前在虚拟内存中文件页占用的内存量
RssShmem: 进程当前在虚拟内存中共享内存页占用的内存量
VmData: 进程数据段占用内存量
VmStk: 进程的栈占用内存量
VmExe: 进程纯代码段占用内存量,不包括链接库。
VmLib: 进程的库段占用内存量
VmPTE: 进程的页表占用内存量
VmSwap: 进程在交换区占用内存量?
2. 实现
static const struct pid_entry tgid_base_stuff[] = { //fs/proc/base.c ONE("status", S_IRUGO, proc_pid_status), }; static const struct pid_entry tid_base_stuff[] = { //fs/proc/base.c ONE("status", S_IRUGO, proc_pid_status), }; int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) //proc/array.c { /* 内核线程返回NULL */ struct mm_struct *mm = get_task_mm(task); ... /* 只有用户线程才有这部分信息打印,内核线程不打印内存相关信息 */ if (mm) { task_mem(m, mm); task_core_dumping(m, mm); task_thp_status(m, mm); mmput(mm); } ... return 0; }
内存相关的统计:
void task_mem(struct seq_file *m, struct mm_struct *mm) //proc/task_mmu.c { unsigned long text, lib, swap, anon, file, shmem; unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; anon = get_mm_counter(mm, MM_ANONPAGES); //mm->rss_stat.count[MM_ANONPAGES]; file = get_mm_counter(mm, MM_FILEPAGES); //mm->rss_stat.count[MM_FILEPAGES]; shmem = get_mm_counter(mm, MM_SHMEMPAGES); //mm->rss_stat.count[MM_SHMEMPAGES]; hiwater_vm = total_vm = mm->total_vm; if (hiwater_vm < mm->hiwater_vm) hiwater_vm = mm->hiwater_vm; hiwater_rss = total_rss = anon + file + shmem; if (hiwater_rss < mm->hiwater_rss) hiwater_rss = mm->hiwater_rss; /* 代码占用的大小 */ text = PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK); //向上向下圆整 text = min(text, mm->exec_vm << PAGE_SHIFT); //这里是以字节为单位 /* lib库占用的大小 */ lib = (mm->exec_vm << PAGE_SHIFT) - text; swap = get_mm_counter(mm, MM_SWAPENTS); //mm->rss_stat.count[MM_SWAPENTS]; /* 对应打印格式,单位KB */ SEQ_PUT_DEC("VmPeak:\t", hiwater_vm); SEQ_PUT_DEC(" kB\n VmSize:\t", total_vm); SEQ_PUT_DEC(" kB\n VmLck:\t", mm->locked_vm); SEQ_PUT_DEC(" kB\n VmPin:\t", atomic64_read(&mm->pinned_vm)); SEQ_PUT_DEC(" kB\n VmHWM:\t", hiwater_rss); SEQ_PUT_DEC(" kB\n VmRSS:\t", total_rss); SEQ_PUT_DEC(" kB\n RssAnon:\t", anon); SEQ_PUT_DEC(" kB\n RssFile:\t", file); SEQ_PUT_DEC(" kB\n RssShmem:\t", shmem); SEQ_PUT_DEC(" kB\n VmData:\t", mm->data_vm); SEQ_PUT_DEC(" kB\n VmStk:\t", mm->stack_vm); seq_put_decimal_ull_width(m, " kB\n VmExe:\t", text >> 10, 8); seq_put_decimal_ull_width(m, " kB\n VmLib:\t", lib >> 10, 8); seq_put_decimal_ull_width(m, " kB\n VmPTE:\t", mm_pgtables_bytes(mm) >> 10, 8); //mm->pgtables_bytes SEQ_PUT_DEC(" kB\n VmSwap:\t", swap); seq_puts(m, " kB\n"); } //CoreDump成员: static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm) { seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state); seq_putc(m, '\n'); } //HTP透明大页: static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm) { bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE); // if (thp_enabled) thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags); seq_printf(m, "THP_enabled:\t%d\n", thp_enabled); }
3. 实验
通过下面脚本可以看到一个进程的所有线程的这些打印都是相同的
P=593; L=""; for I in $(seq 13 29); do L+=$I; L+=p; echo $L; cat /proc/$P/status | sed -n $L; for T in `ls /proc/$P/task/`; do cat /proc/$P/task/$T/status | sed -n $L; done; L=""; done;
标签:status,kB,struct,hiwater,mm,31,vm,内存,rss From: https://www.cnblogs.com/hellokitty2/p/18381653