本文包括如下三部分:

  1. 基本介绍与输出介绍
  2. 第一行基础信息讲解
  3. 详细信息讲解
    3.1 Size
    3.2 Rss
    3.3 Pss、Shared/Private_Clean/Dirty
    3.4 Referenced
    3.5 Anonymous
    3.6 ShmemPmdMapped
    3.7 Shared/Private_Hugetlb
    3.8 Swap
    3.9 SwapPss
    3.10 KernelPageSize、MMUPageSize
    3.11 Locked
    3.12 THPeligible
    3.13 VmFlags

如果对Linux的内存管理机制没有了解过,建议先了解一下,便于理解:Linux内存管理

基本介绍

/proc/PID/smaps 文件是基于 /proc/PID/maps 的扩展,他展示了一个进程的内存消耗,比同一目录下的maps文件更为详细。

值得说明一下的是,每一个VMA(虚拟内存区域,即一个 vm_area_struct 结构指向的内存区域)都有如下的一系列数据

08048000-080bc000 r-xp 00000000 03:02 13130      /bin/bashSize:               1084 kB
Rss:                 892 kB
Pss:                 374 kB
Shared_Clean:        892 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:          892 kB
Anonymous:             0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
THPeligible:           0
VmFlags: rd ex mr mw me dw

第一行基础信息

在讲解字段含义之前,我们必须知道什么匿名映射
在Linux 内存管理的进程用户态内存分布中提到过,映射分为文件映射和匿名映射。

文件映射就是磁盘中的数据通过文件系统映射到内存再通过文件映射映射到虚拟空间,这样,用户就可以在用户空间通过 open ,read, write 等函数区操作文件内容。至于实际的代码,open,read,write,close,mmap... 操作的虚拟地址都属于文件映射。

匿名映射就是用户空间需要分配一定的物理内存来存储数据,这部分内存不属于任何文件,内核就使用匿名映射将内存中的某段物理地址与用户空间一一映射,这样用户就可用直接操作虚拟地址来范围这段物理内存。比如使用malloc申请内存。

  • 08048000-080bc000 是该虚拟内存段的开始和结束位置
  • r-xp 内存段的权限,分别是可读、可写、可运行、私有或共享,最后一位p代表私有,s代表共享
  • 00000000 该虚拟内存段起始地址在对应的映射文件中以页为单位的偏移量,对匿名映射,它等于0或者vm_start/PAGE_SIZE
  • 03:02 文件的主设备号和次设备号。对匿名映射来说,因为没有文件在磁盘上,所以没有设备号,始终为00:00。对有名映射来说,是映射的文件所在设备的设备号。
  • 13130 被映射到虚拟内存的文件的索引节点号,通过该节点可以找到对应的文件,对匿名映射来说,因为没有文件在磁盘上,所以没有节点号,始终为00:00。
  • /bin/bash 被映射到虚拟内存的文件名称。后面带(deleted)的是内存数据,可以被销毁。对有名来说,是映射的文件名。对匿名映射来说,是此段虚拟内存在进程中的角色。[stack]表示在进程中作为栈使用,[heap]表示堆。其余情况则无显示。

第一行的信息完全同于在maps文件中输出的信息。对于不熟悉maps文件的读者可以先了解maps的字段的含义与实现机制。

详细信息

Size虚拟内存空间大小。但是这个内存值不一定是物理内存实际分配的大小,因为在用户态上,虚拟内存总是延迟分配的。这个值计算也非常简单,就是该VMA的开始位置减结束位置

延迟分配就是当进程申请内存的时候,Linux会给他先分配页,但是并不会区建立页与页框的映射关系,意思就是说并不会分配物理内存,而当真正使用的时候,就会产生一个缺页异常,硬件跳转page fault处理程序执行,在其中分配物理内存,然后修改页表(创建页表项)。异常处理完毕,返回程序用户态,继续执行。

Rss:是实际分配的内存,这部分物理内存已经分配,不需要缺页中断就可以使用的。
这里有一个公式计算Rss:
Rss=Shared_Clean+Shared_Dirty+Private_Clean+Private_Dirty

share/private:该页面是共享还是私有。
dirty/clean:该页面是否被修改过,如果修改过(dirty),在页面被淘汰的时候,就会把该脏页面回写到交换分区(换出,swap out)。有一个标志位用于表示页面是否dirty。

share/private_dirty/clean 计算逻辑:
查看该page的引用数,如果引用>1,则归为shared,如果是1,则归为private,同时也查看该page的flag,是否标记为_PAGE_DIRTY,如果不是,则认为干净的。

Pss(proportional set size):是平摊计算后的实际物理使用内存(有些内存会和其他进程共享,例如mmap进来的)。实际上包含下面private_clean+private_dirty,和按比例均分的shared_clean、shared_dirty。

举个计算Pss的例子:
如果进程A有x个private_clean页面,有y个private_dirty页面,有z个shared_clean仅和进程B共享,有h个shared_dirty页面和进程B、C共享。那么进程A的Pss为:
x + y + z/2 + h/3

Referenced:当前页面被标记为已引用或者包含匿名映射(The amount of memory currently marked as referenced or a mapping associated with a file may contain anonymous pages)。

在Linux内存管理的页面替换算法里讲过,当某个页面被访问后,Referenced标志被设置,如果该标志设置了,就 不能将该页移出。

Anonymous:匿名映射的物理内存,这部分内存不来自于文件的内存大小。

ShmemPmdMapped:PMD页面已经被映射的共享(shmem / tmpfs)内存量。在官方文档中,这样解释:"ShmemPmdMapped" shows the ammount of shared (shmem/tmpfs) memory backed by huge pages.

Shared/Private_Hugetlb:由hugetlbfs页面支持的内存使用量,由于历史原因,该页面未计入“ RSS”或“ PSS”字段中。 并且这些没有包含在Shared/Private_Clean/Dirty 字段中。

Swap:存在于交换分区的数据大小(如果物理内存有限,可能存在一部分在主存一部分在交换分区)

SwapPss:这个我并没有找到对应解释,但从源码可以得知,计算逻辑就跟pss一样,只不过针对的是交换分区的内存。

static void smaps_pte_entry(pte_t *pte, unsigned long addr,struct mm_walk *walk)
{struct mem_size_stats *mss = walk->private;struct vm_area_struct *vma = walk->vma;struct page *page = NULL;if (pte_present(*pte)) {//----------------------------------页面在内存中page = vm_normal_page(vma, addr, *pte);} else if (is_swap_pte(*pte)) {//---------------------------页面被swap出swp_entry_t swpent = pte_to_swp_entry(*pte);if (!non_swap_entry(swpent)) {int mapcount;mss->swap += PAGE_SIZE;mapcount = swp_swapcount(swpent);if (mapcount >= 2) {u64 pss_delta = (u64)PAGE_SIZE << PSS_SHIFT;do_div(pss_delta, mapcount);mss->swap_pss += pss_delta; // --------- 如果引用超过1,就将均值加入swap_pss中} else {mss->swap_pss += (u64)PAGE_SIZE << PSS_SHIFT;// ------------ 直接加一个页大小}} else if (is_migration_entry(swpent))page = migration_entry_to_page(swpent);}if (!page)//----------------------------------------------如果页面不存在,就不用更新mss其他信息了;如果存在,调用smaps_account()更新mss。return;
smaps_account(mss, page, PAGE_SIZE, pte_young(*pte), pte_dirty(*pte));
}

KernelPageSize:内核一页的大小
MMUPageSize:MMU页大小,大多数情况下,和KernelPageSize大小一样。

Locked:常驻物理内存的大小,这些页不会被换出。

THPeligible:映射是否符合分配THP的条件。如果为true,则为1,否则为0。 它仅显示当前状态。

THP,透明大页(Transparent Huge Pages),RHEL 6 开始引入,目的是使用更大的内存页面(memory page size) 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。与标准大页的区别在于分配机制,标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。

VmFlags:表示与特定虚拟内存区域关联的内核标志。标志如下:

rd  - readable
wr  - writeable
ex  - executable
sh  - shared
mr  - may read
mw  - may write
me  - may execute
ms  - may share
gd  - stack segment growns down
pf  - pure PFN range
dw  - disabled write to the mapped file
lo  - pages are locked in memory
io  - memory mapped I/O area
sr  - sequential read advise provided
rr  - random read advise provided
dc  - do not copy area on fork
de  - do not expand area on remapping
ac  - area is accountable
nr  - swap space is not reserved for the area
ht  - area uses huge tlb pages
ar  - architecture specific flag
dd  - do not include area into core dump
sd  - soft-dirty flag
mm  - mixed map area
hg  - huge page advise flag
nh  - no-huge page advise flag
mg  - mergable advise flag

参考文章:
Linux官方文档
Linux smaps接口文件结构
linux proc maps文件分析
linux proc maps文件分析
匿名文件映射问题 (概念不清晰)
Linux中各种设备及设备号
Linux smaps接口文件结构
闲聊Linux内存管理(1)
Linux物理内存回收机制
Linux /proc/$pid/smaps的含义
Linux传统Huge Pages与Transparent Huge Pages再次学习总结
Linux内存管理 一个进程究竟占用多少空间?-VSS/RSS/PSS/USS
linux 内存查看方法:meminfo\maps\smaps\status 文件解析

作者:墨染书
链接:https://www.jianshu.com/p/8203457a11cc
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Linux内存管理 -- /proc/{pid}/smaps讲解相关推荐

  1. Linux内存管理 -- smaps讲解

    基本介绍 /proc/PID/smaps 文件是基于 /proc/PID/maps 的扩展,他展示了一个进程的内存消耗,比同一目录下的maps文件更为详细. 值得说明一下的是,每一个VMA(虚拟内存区 ...

  2. linux内存管理详解,Linux内存管理图文讲解.pdf

    Linux内存管理图文讲解 逻辑地址.线性地址.物理地址和虚拟地址 一.概念 物理地址(physical address) 用于内存芯片级的单元寻址,和处理器和 CPU 连接的地址总线相对应. 这个概 ...

  3. 进程内存信息 /proc/[pid]/maps /proc/[pid]/smaps /proc/[pid]/status

    /proc/[pid]/maps /proc/[pid]/smaps /proc/[pid]/status

  4. 郝健: Linux内存管理学习笔记-第3节课

    摘要 进程的虚拟地址空间VMA(Virtual Memory Area) Pagefault的几种可能性.VMA的作用.major缺页和minor缺页 进程内存消耗的4个概念:vss.rss.pss和 ...

  5. 深入理解Linux内存管理(0.3)

    学习方法论 写作原则 标题括号中的数字代表完成度与完善度 0.0-1.0 代表完成度,1.1-1.5 代表完善度 0.0 :还没开始写 0.1 :写了一个简介 0.3 :写了一小部分内容 0.5 :写 ...

  6. Linux内存管理【转】

    转自:http://www.cnblogs.com/wuchanming/p/4360264.html 转载:http://www.kerneltravel.net/journal/v/mem.htm ...

  7. 一文掌握 Linux 内存管理

    作者:dengxuanshi,腾讯 IEG 后台开发工程师 以下源代码来自 linux-5.10.3 内核代码,主要以 x86-32 为例. Linux 内存管理是一个很复杂的"工程&quo ...

  8. Linux内存管理 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-4491368.html Linux内存管理 摘要:本章首先以应用程序开发者的角度审视Linux的进程内存管理 ...

  9. Linux内存管理:分页机制

    <Linux内存管理:内存描述之内存节点node> <Linux内存管理:内存描述之内存区域zone> <Linux内存管理:内存描述之内存页面page> < ...

  10. Linux内存管理:NUMA技术详解(非一致内存访问架构)

    图片来源:https://zhuanlan.zhihu.com/p/68465952 <Linux内存管理:转换后备缓冲区(TLB)原理> <内存管理:Linux Memory Ma ...

最新文章

  1. monorepo_Monorepo开发的要点
  2. Vivado篇(一)Notepad++编写的Verilog文件导入Vivado,中文注释乱码问题
  3. NOJ37 回文字符串---整理一下都是各种回文类型啊,
  4. 使用pil读取gif图有些位置为黑色_使用 Pillow 快速创建 GIF 动图
  5. 45个极具冲击力的WordPress摄影网站模板
  6. 【Spring】Spring 如何解决循环依赖问题
  7. [小笔记]TypeScript/JavaScript模拟Python中的Range函数
  8. 初识IOS,Label控件的应用。
  9. [转]:vue-cli3.0配置详解
  10. json格式转换工具包
  11. 关于DBSCAN聚类算法
  12. 磁珠 符号_贴片磁珠规格
  13. 网站服务器进不去可以加速进去吗,让网页打开加速的方法
  14. Cryengine5.3
  15. Centos7安装Docker,阿里源,网易镜像
  16. 王阳明《没有秘密的你》开播 超A男神化身正义律师叱咤律界风云
  17. 湖南广电台长吕焕斌:湖南电视台的新媒体发展战略
  18. Lazada跨境直播,双11直播成绩傲娇!如何做到大促流量销量双收割?
  19. 《java核心技术36讲》学习笔记-------杨晓峰(极客时间)
  20. Automated Phrase

热门文章

  1. 1121 - Reverse the lights 思维题
  2. 实现日志文件直接导入数据库
  3. [置顶] 63行代码完美实现html5 贪吃蛇游戏
  4. 汪洋大海中的一块绿地
  5. python爬虫什么框架好用_推荐十款高效率的Python爬虫框架,你用过几个?
  6. python3怎么安装opencv_如何在Ubuntu 16.04上安装支持Python 3.x的OpenCV
  7. CKEditor4x word导入不保存格式的解决方案
  8. AES算法,DES算法,RSA算法JAVA实现
  9. XAML实例教程系列 - 标记扩展(Markup Extensions)
  10. dubbo入门级梳理