mm3
进程VMA
每一个进程都有0GB~3GB虚拟地址,内核虚拟地址只有一个3GB~4GB,如下:
3GB~4GB 内核空间
/ | \
/ | \
---------------------------------------
0GB~3GB 0GB~3GB 0GB~3GB 用户空间
A进程 B进程 C进程因此不同进程可以有相同虚拟地址,但是不同进程的页表不一样,所以相同虚拟地址映射到不同的物理地址中。
每一个进程的0GB~3GB虚拟地址,只是用某几段区域,不会全部使用完;一般有text 段、data 段、BSS 段、Heap 段、Stack 段等,每一段虚拟地址区域就是一个vma。
将每一个进程的所有段通过链表方式进行连接,如下:
struct task_struct {
struct mm_struct *mm
};
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
};
struct vm_area_struct {
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next;
};查看一个进程vma的分布情况:
page fault的可能性
访问没有VMA的非法区内存区域,应用程序出现segv
heap区域vma(R+W权限),指向页表是R权限;因此第一次写操作时,发生page fault,申请一页内存,页表权限是R+W,此过程称为minor
代码段vma(R+X权限),执行W操作,权限不对,应用程序出现segv
代码段 vma(R+X权限),执行X操作,如果页表不存在,需要申请页,读出代码段,有会硬盘I/O操作,此过程称为major
进程内存消耗的4个概念:VSS、RSS、PSS和USS
VSS:虚拟内存占用空间,VMA大小
RSS:实际内存占用空间,私有数据+共享内存
PSS:实际内存占用空间,私有数据+共享内存/共享数量
USS:实际内存占用空间,私有数据
查看VSS/RSS/PSS/USS占用大小,如下:
内存泄露的界定方法?
原理:连续多点采样法,随着运行时间越久,进程使用内存越多
先用free命令判断系统是否内存泄露?
分别检查应用空间与内核空间是否内存泄露?
应用空间内存泄露检查步骤:
连续多点采样后,
USS从560 -> 608 -> 644,判断应用空间内存泄露
通过valgrind进行检测,能够精确定位哪一行源码发生内存泄露,如下:
或者通过asan进行检测,但是需要gcc版本大于等于8,能够精确定位哪一行源码发生内存泄露,如下:
内核空间内存泄露检查步骤:
查看内核空间的内存实时情况,判断内核空间内存泄露
linux kernel启动中DEBUG_KMEMLEAK功能,进行定位哪里出现内存泄露
Last updated
Was this helpful?