Linux 操作系统:/proc/[pid]/smaps 与 /proc/[pid]/statm

2024-03-19

我想计算单个进程的内存使用情况。经过一些研究后,我发现了 smaps 和 statm。

首先什么是smaps和statm?有什么不同?

statm 有一个 RSS 字段,在 smaps 中我总结了所有 RSS 值。但对于同一过程,这些值是不同的。我知道 statm 以页为单位。为了进行比较,我将该值转换为 kb,就像 smap 中一样。但这些值并不相等。 为什么这两个值不同,即使它们代表同一进程的 rss 值?

statm
232214 80703 7168 27 0 161967 0 (measured in pages, pages size is 4096)

smaps
Rss 1956

我的目标是计算单个进程的内存使用情况。我对两种价值观感兴趣。 USS 和 PSS。 我可以仅使用 smap 来获得这两个值吗?这个值正确吗? 另外,我想以百分比形式返回该值。


I think statm是一个近似的简化smaps,获得成本更高。我看了源码后得出这个结论:

smaps

您看到的信息smaps定义于/fs/proc/task_mmu.c https://github.com/torvalds/linux/blob/master/fs/proc/task_mmu.c#L631:

static int show_smap(struct seq_file *m, void *v, int is_pid)
{
        (...)

        struct mm_walk smaps_walk = {
                .pmd_entry = smaps_pte_range,
                .mm = vma->vm_mm,
                .private = &mss,
        };

        memset(&mss, 0, sizeof mss);
        walk_page_vma(vma, &smaps_walk);
        show_map_vma(m, vma, is_pid);

        seq_printf(m,
                (...)
                "Rss:            %8lu kB\n"
                (...)
                mss.resident >> 10,

中的信息mss被使用walk_page_vma定义于/mm/pagewalk.c https://github.com/torvalds/linux/blob/master/mm/pagewalk.c#L288。但是,那mss member resident未填写walk_page_vma- 反而,walk_page_vma调用指定的回调smaps_walk:

.pmd_entry = smaps_pte_range,
.private = &mss,

像这样:

  if (walk->pmd_entry)
      err = walk->pmd_entry(pmd, addr, next, walk);

那么我们的回调是做什么的,smaps_pte_range in /fs/proc/task_mmu.c https://github.com/torvalds/linux/blob/master/fs/proc/task_mmu.c, 做? 它调用smaps_pte_entry and smaps_pmd_entry在某些情况下,两者都调用statm_account(),这反过来...升级resident尺寸!所有这些函数都在已经链接的中定义task_mmu.c所以我没有发布相关的代码片段,因为它们可以在链接的源中轻松看到。

PTE 代表页表条目,PMD 代表页面中间目录。因此,基本上我们会迭代与给定进程关联的页面条目,并根据情况更新 RAM 使用情况。

statm

您看到的信息statm定义于/fs/proc/array.c https://github.com/torvalds/linux/blob/master/fs/proc/array.c:

int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
                struct pid *pid, struct task_struct *task)
{
        unsigned long size = 0, resident = 0, shared = 0, text = 0, data = 0;
        struct mm_struct *mm = get_task_mm(task);

        if (mm) {
                size = task_statm(mm, &shared, &text, &data, &resident);
                mmput(mm);
        }
        seq_put_decimal_ull(m, 0, size);
        seq_put_decimal_ull(m, ' ', resident);
        seq_put_decimal_ull(m, ' ', shared);
        seq_put_decimal_ull(m, ' ', text);
        seq_put_decimal_ull(m, ' ', 0);
        seq_put_decimal_ull(m, ' ', data);
        seq_put_decimal_ull(m, ' ', 0);
        seq_putc(m, '\n');
        return 0;
}

这次,resident被填充为task_statm。这个有两种实现,一种是/fs/proc/task_mmu.c https://github.com/torvalds/linux/blob/master/fs/proc/task_mmu.c和第二名/fs/proc/task_nomm.c https://github.com/torvalds/linux/blob/master/fs/proc/task_nommu.c。由于它们几乎肯定是相互排斥的,因此我将重点关注task_mmu.c(其中还包含task_smaps)。在这个实现中我们看到

unsigned long task_statm(struct mm_struct *mm,
                    unsigned long *shared, unsigned long *text,
                    unsigned long *data, unsigned long *resident)
{
        *shared = get_mm_counter(mm, MM_FILEPAGES);
        (...)
        *resident = *shared + get_mm_counter(mm, MM_ANONPAGES);
        return mm->total_vm;
}

它查询一些计数器,即MM_FILEPAGES and MM_ANONPAGES。这些计数器在内存的不同操作期间被修改,例如do_wp_page定义于/mm/memory.c https://github.com/torvalds/linux/blob/master/mm/memory.c。所有修改似乎都是由位于的文件完成的/mm/而且好像还不少,所以这里就不一一列举了。

结论

smaps对所有引用的内存区域进行复杂的迭代并进行更新resident使用收集到的信息的大小。statm使用其他人已经计算出的数据。

最重要的部分是,虽然smaps每次以独立的方式收集数据,statm使用在进程生命周期期间递增或递减的计数器。有很多地方需要做记账,也许有些地方没有像他们应该的那样升级柜台。这就是为什么国际海事组织statm劣于smaps,即使需要更少的 CPU 周期来完成。

请注意,这是我根据常识得出的结论,但我可能是错的 - 也许计数器递减和递增中没有内部不一致,相反,它们对某些页面的计数可能与smaps。在这一点上,我相信将其交给一些经验丰富的内核维护人员是明智的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 操作系统:/proc/[pid]/smaps 与 /proc/[pid]/statm 的相关文章

  • 具有少量父设备属性的 udev 规则

    我需要复杂且通用的udev规则来确定插入任何 USB 集线器的特定端口的 USB 设备 所以 我必须结合设备树不同层的父属性 我有这个 udevadm info query all name dev ttyUSB0 attribute wa
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • python:numpy 运行脚本两次

    当我将 numpy 导入到 python 脚本中时 该脚本会执行两次 有人可以告诉我如何阻止这种情况 因为我的脚本中的所有内容都需要两倍的时间 这是一个例子 usr bin python2 from numpy import print t
  • 如何成功使用RDAP协议代替whois

    我对新的 RDAP 协议有点困惑 也不知道何时进一步追求它有意义 在我看来 每个人都同意它是 whois 的继承者 但他们的数据库似乎是空的 在 ubuntu 上我尝试了 rdapper nicinfo 甚至他们的 RESTful API
  • 操作系统什么时候清除进程的内存

    进程在某些操作系统上成功或异常终止 操作系统何时决定擦除分配给该进程的内存 数据 代码等 在退出时或当它想为新进程分配内存时 这个清除内存分配过程在所有操作系统 winXP Win7 linux Mac 上都相同吗 据我了解 页表具有该进程
  • 如何在我的 AWS EC2 实例上安装特定字体?

    我有一个在 AWS EC2 Amazon Linux Elastic Beanstalk 实例上运行的 Python 应用程序 该实例需要某些特定字体才能生成输出 并且想知道如何在部署或实例启动过程中安装它们 我的代码在本地计算机 OS X
  • InstaPy:“错误,无法确定 64 位 Linux 的正确文件名”

    有人知道如何解决或解决这个问题吗 来自控制台的堆栈跟踪 执行后报告错误 InstaPy Version 0 6 9 Workspace in use home zanettra InstaPy Error unable to determi
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 伊迪德信息

    重新定义问题 有什么方法可以获取所连接显示器的序列号吗 我想收集显示器的Eid信息 当我使用 logverbose 选项运行 X 时 我可以从 xorg 0 log 文件中获取它 但问题是 如果我切换显示器 拔出当前显示器 然后插入另一个显
  • Java:为什么它使用固定数量的内存?或者它如何管理内存?

    JVM 似乎使用了一些固定数量的内存 至少我经常看到参数 Xmx 对于最大尺寸 和 Xms 对于初始大小 这表明 我感觉 Java 应用程序不能很好地处理内存 我注意到一些事情 即使一些非常小的示例演示应用程序也会加载大量内存 也许这是因为
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • Docker:处理 tar 文件时出错(退出状态 1):设置枢轴目录时出错:不是目录

    我是 Docker 新手 不知道是什么原因导致此错误或如何诊断它 任何有关此问题的具体帮助或有关首先检查何处以诊断此类问题的提示将不胜感激 我的 Dockerfile FROM java 8 Install maven RUN apt ge
  • 设置 Apache POI 的路径

    我想创建 Excel 文件并使用 java 程序在该文件中写入数据 That is here http www techbrainwave com p 554我在 java 文件所在的位置提取了 Apache POI 并将该路径包含在路径变
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get

随机推荐

  • 如何卸载Keras?

    我已经使用以下命令安装了 Keras sudo pip install keras 它安装正确并且工作正常 直到我尝试导入应用程序模块 from keras applications vgg16 import VGG16 Using The
  • 如何解决 Spark JDBC 的编码问题?

    我在 Oracle 中有一个表 其中有一些俄语记录 当我使用 Spark JDBC 读取此表时 我收到的数据帧的值不正确 您知道为什么会发生这种情况以及如何解决吗 executes given query using jdbc def ex
  • 将UserTrackingMode 设置为 MKUserTrackingModeFollow 而不更改缩放级别

    在 Apple 文档中设置用户跟踪模式 动画 https developer apple com library ios documentation MapKit Reference MKMapView Class index html a
  • 以 Kotlin 方式获取字符串中包含的子字符串的索引

    我想实现一个函数 它将返回指定字符串中子字符串的索引 现在我用Java风格做了 public fun String indexesOf substr String ignoreCase Boolean true List
  • 使用 SASS 函数自动设置嵌套元素的背景颜色

    我正在制作一个多级导航系统 并希望每个级别的背景颜色变暗 20 因此第 1 级 fff 第 2 级 ccc 第 3 级 999 等等 一定有一种很棒的方法可以使用 SASS 函数动态地自动化这个过程 但我不太明白如何设置该语句 有人能指出我
  • ActiveRecord 搜索返回“语法错误或访问冲突”错误

    在我的 Yii 应用程序中 我有一个模型代表siteconfig表并有四列 integer config id string key string value string update time 我使用Gii创建了一个模型 以确保我不会犯
  • 如何*快速*将许多 .txt 文件转换为 .xls 文件

    更新 我刚刚发现拥有更强大服务器的人将完成分配给我的任务 所以我没有让这个程序足够快也没关系 然而 下面的答案 自动化 Excel 有助于使程序速度提高三倍 因此我将其推荐给文件较少 但仍然较多 的人 我正在尝试将许多 超过 300 000
  • Java泛型通配符及其局限性

    我有一个由两部分组成的问题 我的书指出 如果指定通配符时没有大写字母 绑定 那么只能调用 Object 类型的方法 通配符类型的值 我不知道这意味着什么 这是什么意思 另外 通配符类型 无界和有界 有哪些限制 例如 如果我有一个参考MyCl
  • 来自相机的原始图像数据

    我一直在这个论坛上上下搜索 但找不到我真正需要的东西 我想从相机获取原始图像数据 到目前为止 我尝试通过该方法从 imageDataSampleBuffer 中获取数据captureStillImageAsynchronouslyFromC
  • 如何组合多个 TypeScript 类装饰器?

    我有一个类装饰器家族 我在很多类中重复使用它们 与此类似的东西 foo bar baz export class MyClass 由于我在多个类中使用这三个装饰器 我真的很想将其分解为一个装饰器 如下所示 standard export c
  • 如何获取 C# 中所有已加载类型的列表?

    我需要检索从给定的程序集加载的所有枚举 List
  • 导入错误? (Python 3.2)

    我有自己的名为 v systems 的模块 并且我正在尝试将该模块导入到另一个 python 文件中 该文件也保存在与保存文件 v systems 相同的目录中 我需要将其导入为import v systems as vs或者即使我尝试导入
  • 以概率打乱 JS 数组

    假设我有一个像这样的数组 const alphabet a b c d 这代表 4 名政治候选人和一次等级选择投票 其中候选人a是首选 b是第二选择等等 我想将其打乱为一堆随机顺序 但在这种情况下我想要a大概以 60 的比例最先出现 b第二
  • Android Studio - 没有可调试的应用程序

    我尝试调试 Android 应用程序的发布版本 但 Android Studio 无法附加调试器 它找不到我正在运行的应用程序的 Android 进程 在设备控制台下 只有一条消息 没有可调试的应用程序 您还应该激活 工具 gt Andro
  • CMake 中的第三方库

    我在我的项目中使用 cmake 但我在子目录 例如 lib 中有另一个库 它使用普通的 Makefile 作为构建过程的一部分 如何指示 CMake 运行 lib 中的 Makefile 解决方案是使用 execute process CO
  • 安装后将 Javacard 小程序标记为隐式可选(默认小程序)

    我正在寻找一种方法 将小程序标记为隐式可选 默认选择 小程序 然后将其上传并安装在全球平台 http www globalplatform org JCOP 2 4 2 R1 http www nxp com products identi
  • 使用 JAVA 在 S3 存储桶上放置/读取文件

    我试图将文件放在 S3 上并使用 JAVA 从 S3 存储桶读取文件 但遇到无法执行 HTTP 请求 当我尝试列出存储桶时 它工作正常 对我来说 似乎只有 listBuckets 方法在工作 而所有其他方法 如 putObject list
  • Spring Reactive xml有效负载异常java.lang.IllegalStateException:无法解析类型为“reactor.core.publisher.Mono”的参数0

    我有一个春季启动应用程序 尝试通过邮递员将 xml 有效负载发送到 Post 请求 我得到以下内容例外 java lang IllegalStateException Failed to resolve argument 0 of type
  • Marathon 上的临时任务

    在此之前 我要说的是 我是 Mesosphere 堆栈的新手 我正在尝试将现有的 Rails 应用程序部署迁移到 Mesos 到目前为止我已经成功 但目前我正在运行迁移和种子 通过 Rake 任务 我没有看到一个很好的方法来实现它因为这些任
  • Linux 操作系统:/proc/[pid]/smaps 与 /proc/[pid]/statm

    我想计算单个进程的内存使用情况 经过一些研究后 我发现了 smaps 和 statm 首先什么是smaps和statm 有什么不同 statm 有一个 RSS 字段 在 smaps 中我总结了所有 RSS 值 但对于同一过程 这些值是不同的