How to accout max_rss precisely
Hi, I'm working on a utility to report the maximum memory usage of a certain program. I intend to show the max_rss of this process and its children, but it's hard to use getrusage to get the RSS precisely, so I'm trying to leverage cgroups. However on the document of cgroups v2, `memory.peak` says: The max memory usage recorded for the cgroup and its descendants since the creation of the cgroup. It didn't explain the composition of memory usage. So I want to ask that is the memory usage in `memory.peak` the maximum of RSS? I made a quick test on an empty program like: ```c // a.c int main() {} ``` It shows that `memory.peak` of this program is ~500KiB, which does not make sense to me. I also wonder how to implement the same function under OS without cgroups, like BSD and macOS. Thanks
On Sat, 01 Jun 2024 15:01:32 +0800, 杨贺然 said:
// a.c int main() {}
It shows that `memory.peak` of this program is ~500KiB, which does not make sense to me.
Makes sense to me... [~] cat > testnull.c int main() {} [~] gcc testnull.c [~] ldd a.out linux-vdso.so.1 (0x00007efc6a650000) libc.so.6 => /lib64/libc.so.6 (0x00007efc6a43d000) /lib64/ld-linux-x86-64.so.2 (0x00007efc6a652000) [~] objdump -d a.out a.out: file format elf64-x86-64 Disassembly of section .init: 0000000000401000 <_init>: 401000: f3 0f 1e fa endbr64 401004: 48 83 ec 08 sub $0x8,%rsp 401008: 48 8b 05 d1 2f 00 00 mov 0x2fd1(%rip),%rax # 403fe0 <__gmon_start__@Base> 40100f: 48 85 c0 test %rax,%rax 401012: 74 02 je 401016 <_init+0x16> 401014: ff d0 call *%rax 401016: 48 83 c4 08 add $0x8,%rsp 40101a: c3 ret Disassembly of section .text: 0000000000401020 <_start>: 401020: f3 0f 1e fa endbr64 401024: 31 ed xor %ebp,%ebp 401026: 49 89 d1 mov %rdx,%r9 401029: 5e pop %rsi 40102a: 48 89 e2 mov %rsp,%rdx 40102d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 401031: 50 push %rax 401032: 54 push %rsp 401033: 45 31 c0 xor %r8d,%r8d 401036: 31 c9 xor %ecx,%ecx 401038: 48 c7 c7 06 11 40 00 mov $0x401106,%rdi 40103f: ff 15 93 2f 00 00 call *0x2f93(%rip) # 403fd8 <__libc_start_main@GLIBC_2.34> 401045: f4 hlt 401046: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) 40104d: 00 00 00 (.....) Basically, its not *really* a totally null program. You've got the dynamic loader ld-linux running first, which then *doesn't* run main() directly, but rather invokes _start, which needs to happen so that __libc_start_main can get called and initialize stuff lie stdio, malloc, and other such t hings, before it finally calls main(). Personally, I'm surprised that ld-linux and glibc initialization can finish without going over 500k - even more so if shared library text pages are included in memory.peak. Somebody else can wade into that mess, I admit having been around since kernel 2.5.47 or so, and I never did understand the memory accounting for shared text pages....
participants (2)
-
Valdis Klētnieks -
杨贺然