0

我编写了一个用于监视子进程资源的程序。我使用 wait4 函数的第四个参数来获取子进程的 CPU 使用率,效果很好。但我可以用它来获取内存使用情况,它看起来与“ps”的输出不同。我也尝试解析/proc/pid/status,但有时它并不准确,因为某些子进程解析得太快。有人可以给我一些建议或解决方案吗?非常感谢。

4

1 回答 1

2

一旦进程终止,即使进程入口仍然存在于内核中,该进程的所有资源都会被内核释放。所以,我不希望能够从 /proc 读取进程的内存大小。

此外,该进程没有“使用的最大内存”统计信息。

我能想到的确定进程最大内存量的唯一方法如下:

  1. 在执行时定期对进程状态进行采样并获取当前内存使用情况,
  2. 用于strace捕获进程进行的所有系统调用并对其进行处理以确定进程使用了​​多少内存,或者
  3. 使用共享库来拦截进程进行的内存分配系统调用,捕获详细信息并找到报告的方法

除非绝对需要非常高的准确性,否则我可能会选择(1)。

可能有分析或统计工具可以帮助完成这项任务,但我不知道。


使用跟踪

这是一个程序,说明了strace用于此目的的用途:

allocit.c

#include <stdio.h>
#include <stdlib.h>

int main ()
{
        int     cur;

        cur = 0;
        while ( cur < 1000 )
        {
                malloc(1024);
                cur++;
        }

        return  0;
}

使用 strace ( strace ./allocit) 运行它会得到如下输出:

execve("./allocit", ["./allocit"], [/* 49 vars */]) = 0
brk(0)                                  = 0x1b991000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae49dccd000
uname({sys="Linux", node="fearless.office.tmcs", ...}) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/home/jdoe/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/jdoe/lib/tls/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/home/jdoe/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/jdoe/lib/tls", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/home/jdoe/lib/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/jdoe/lib/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/home/jdoe/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/jdoe/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/software/ticketmaster/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/software/ticketmaster/lib/tls/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/software/ticketmaster/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/software/ticketmaster/lib/tls", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/software/ticketmaster/lib/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/software/ticketmaster/lib/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/software/ticketmaster/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/software/ticketmaster/lib", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/11.2/client64/lib/tls/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/oracle/11.2/client64/lib/tls/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/11.2/client64/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/oracle/11.2/client64/lib/tls", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/11.2/client64/lib/x86_64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/oracle/11.2/client64/lib/x86_64", 0x7fff896b2900) = -1 ENOENT (No such file or directory)
open("/usr/lib/oracle/11.2/client64/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/oracle/11.2/client64/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=123338, ...}) = 0
mmap(NULL, 123338, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2ae49dcce000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\332!\2359\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1717800, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae49dced000
mmap(0x399d200000, 3498328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x399d200000
mprotect(0x399d34e000, 2093056, PROT_NONE) = 0
mmap(0x399d54d000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14d000) = 0x399d54d000
mmap(0x399d552000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x399d552000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae49dcee000
arch_prctl(ARCH_SET_FS, 0x2ae49dcee210) = 0
mprotect(0x399d54d000, 16384, PROT_READ) = 0
mprotect(0x399d01b000, 4096, PROT_READ) = 0
munmap(0x2ae49dcce000, 123338)          = 0
brk(0)                                  = 0x1b991000
brk(0x1b9b2000)                         = 0x1b9b2000
brk(0x1b9d3000)                         = 0x1b9d3000
brk(0x1b9f4000)                         = 0x1b9f4000
brk(0x1ba15000)                         = 0x1ba15000
brk(0x1ba36000)                         = 0x1ba36000
brk(0x1ba57000)                         = 0x1ba57000
brk(0x1ba78000)                         = 0x1ba78000
brk(0x1ba99000)                         = 0x1ba99000
exit_group(0)                           = ?

注意所有brk()用于扩展堆的调用。

于 2013-09-02T03:43:44.040 回答