[转帖]Linux内存管理 -- /proc/{pid}/smaps讲解

linux,内存,管理,proc,pid,smaps,讲解 · 浏览次数 : 0

小编点评

## Rss 计算公式 Rss = Shared_Clean + Shared_Dirty + Private_Clean + Private_Dirtyshare / private * **Shared_Clean**:共享内存中已使用的字节数量 * **Shared_Dirty**:共享内存中已修改的字节数量 * **Private_Clean**:私有内存中已使用的字节数量 * **Private_Dirty**:私有内存中已修改的字节数量 * **private**:页面类型 **page_type**可以根据页面是否被修改过以及其他条件进行区分: * **dirty**:页面被修改过 * **clean**:页面未被修改过 **Pss (proportional set size)** 是一个平摊计算后的实际物理使用内存大小,包含**private_clean**、**private_dirty**和**shared_clean**。 **Pss 的计算公式:** Pss = x + y + z/2 + h/3 * **x**: Private_clean 页面数量 * **y**: Private_dirty 页面数量 * **z**: Shared_clean仅与进程B共享的页面数量 * **h**: Shared_dirty 页面数量和进程B、C共享的页面数量

正文

https://www.jianshu.com/p/8203457a11cc

 

本文包括如下三部分:

  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/bash

Size:               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 文件解析

与[转帖]Linux内存管理 -- /proc/{pid}/smaps讲解相似的内容:

[转帖]Linux内存管理 -- /proc/{pid}/smaps讲解

https://www.jianshu.com/p/8203457a11cc 本文包括如下三部分: 基本介绍与输出介绍 第一行基础信息讲解 详细信息讲解3.1 Size3.2 Rss3.3 Pss、Shared/Private_Clean/Dirty3.4 Referenced3.5 Anonymo

[转帖]Linux kernel内存管理之overcommit相关参数

前言 了解 linux kernel内存管理,首先可以从用户空间的角度来看kernel的内存管理,执行ls /proc/sys/vm的命令,就可以看到vm运行的所有参数,其中就包含了跟overcommit相关的参数。 Memory overcommit概念介绍 要了解这类参数首先要理解什么是comm

[转帖]Linux内存管理——大部分人没有掌握的shmall和shmmax参数

https://zhuanlan.zhihu.com/p/551804053 内核中的 shmall 和 shmmax 参数 SHMMAX= 配置了最大的内存segment的大小 >这个设置的比SGA_MAX_SIZE大比较好。 SHMMIN= 最小的内存segment的大小 SHMMNI= 整个系

[转帖]Linux内存泄露案例分析和内存管理分享

https://zhuanlan.zhihu.com/p/583922188 一、问题 近期我们运维同事接到线上LB(负载均衡)服务内存报警,运维同事反馈说LB集群有部分机器的内存使用率超过80%,有的甚至超过90%,而且内存使用率还再不停的增长。接到内存报警的消息,让整个团队都比较紧张,我们团队负

[转帖]Linux内存–PageCache

https://plantegg.github.io/2020/11/15/Linux%E5%86%85%E5%AD%98--pagecache/ 本系列有如下几篇 Linux 内存问题汇总 Linux内存–PageCache Linux内存–管理和碎片 Linux内存–HugePage Linux

[转帖]Linux内存–HugePage

https://plantegg.github.io/2020/11/15/Linux%E5%86%85%E5%AD%98--HugePage/ 本系列有如下几篇 Linux 内存问题汇总 Linux内存–PageCache Linux内存–管理和碎片 Linux内存–HugePage Linux内

[转帖]Linux中的Page cache和Buffer cache详解

1、内存情况 在讲解Linux内存管理时已经提到,当你在Linux下频繁存取文件后,即使系统上没有运行许多程序,也会占用大量的物理内存。这是因为当你读写文件的时候,Linux内核为了提高读写的性能和速度,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存)。即使你的程序运行结

[转帖]Linux性能调优之内存负载调优的一些笔记

https://zhuanlan.zhihu.com/p/548770928 写在前面 整理一些Linux内存调优的笔记,分享给小伙伴 博文没有涉及的Demo,理论方法偏多,可以用作内存调优入门 博文内容涉及: Linux内存管理的基本理论 寻找内存泄露的进程 内存交换空间调优 不同方式的内存回收

[转帖]Linux系统:page fault

Linux进程如何访问内存 Linux下,进程并不是直接访问物理内存,而是通过内存管理单元(MMU)来访问内存资源,原因后面会讲到。 为什么需要虚拟内存地址空间 假设某个进程需要4MB的空间,内存假设是1MB的,如果进程直接使用物理地址,这个进程会因为内存不足跑不起来。既然进程不是直接访问物理内存,

[转帖]linux性能优化-内存回收

linux文件页、脏页、匿名页 缓存和缓冲区,就属于可回收内存。它们在内存管理中,通常被叫做文件页(File-backed Page)。通过内存映射获取的文件映射页,也是一种常见的文件页。它也可以被释放掉,下次再访问的时候,从文件重新读取。 大部分文件页,都可以直接回收,以后有需要时,再从磁盘重新读