自 90 年代末以来,我一直是开源 IRC 机器人的开发/维护者。我们的目标始终是使其在较小的内存占用范围内尽可能通用和有用。
在 2000 年代,我还编写了一些概念验证代码,将有用的程序压缩到只有 4kB RSS,这在 2.4 内核上实现起来并不难。我用 init 和 Agetty 实现了这一点;也就是说,我让它们在单个 4kB 内存页面内常驻运行以履行其职责。
现在,当有一天我要求我的机器人报告其内存使用情况时,它的回应如下:
[Mar 27 2018] <bot> VM 1000 kB (Max 2988 kB), RSS 4 kB [ Code 212 kB, Data 68 kB, Libs 556 kB, Stack 132 kB ]
为了在内核 2.4 上获得 4kB RSS,我必须将所有代码、rodata 和堆栈段映射到同一页面。由于我没有对机器人执行此操作,因此理论限制也应该是 12kB。但对于更高版本的内核,似乎有一些额外的加速器映射,因此即使取消映射堆栈和rodata,仍然会留下 12kB 的映射。
该机器人已与 libmusl 链接,因此其运行时的“正常”标准 RSS 大小为 54kB。我确实创建了一个 ld 脚本来将函数重新排序为很少使用的核心必需块,但即使在理论上,4kB 仍然不合理。该系统是 Xeon,具有充足的物理内存,无交换且无系统负载,因此不存在换出页面的压力。
知道这里发生了什么吗?我仍然对将所有内容重新映射到单个 4kB 页面的可能性感兴趣,尽管到目前为止我只将其降至 12kB 可重现和 8kB 不可重现。
机器人从 /proc 读取 RSS,并仅报告其读取的未更改内容。ps aux
显示与机器人报告的相同的 VSZ 和 RSS。
答案1
这不是一个答案。(文本太复杂,无法编辑为评论)
我认为回答你的问题首先需要精确说明 4 系列中以 RSS 形式报告的值的确切含义。它具体代表什么?
因为我确信自 2.4 以来微积分已经(巨大)改变了。
我记得的第一个变化是在 2.6 时代,当时 Andrew Morton & Al.想要对 RSS 实施一些 RLIMIT。
当版本:
- io 映射设备区域
- 非线性映射
- 巨大的内存
- 共享正常内存
- SysV-IPC共享内存
- 不共享普通内存
我记得,每个人都同意不应再考虑 VM_IO 部分,并且为了避免考虑共享库的完整大小而施加了很大的压力。
其他部分(Hugetlb 和共享正常内存)很难达成共识,因此需要将它们分为几个子类别。
某种我没有准确理解的毛茸茸的狗故事。我只是想指出,4 中 RSS 的含义肯定与 2.4 中的 RSS 含义不同,因此对于同一可执行文件,报告的值可能会有很大差异。
祝你好运。
一旦发布了一些好的答案,我当然会删除这篇文章。