linux下使用getrusage动态监测内存使用情况
结论
无法使用:struct rusage中的ru_maxrss字段表示最大常驻集大小,在内存释放后无法变为0,还是目前已用的最大常驻集大小。
1.ru_maxrss
表示最大常驻集大小,而测试结果表示驻留集大小只会由小变大,不会由大变小,导致只能检测出程序的进程使用内存变大的情况。
但是按理说:进程使用的内存并不是只会由小变大,如果进程释放了一部分内存,那么其驻留集大小也会相应地减小。
2.其他字段基本没用
还是解析status文件读取内存使用情况吧。
函数介绍
getrusage
函数:
#include <sys/time.h>
#include <sys/resource.h>
int getrusage(int who, struct rusage *usage);
其中,who
参数指定所要查询的资源类型,RUSAGE_SELF
表示查询当前进程自身的资源使用情况,RUSAGE_CHILDREN
表示查询所有子进程的资源使用情况,RUSAGE_THREAD
表示查询当前线程的资源使用情况(需要支持线程的操作系统才能使用)
而usage
参数是一个struct rusage
类型的结构体指针,用于存储查询结果。struct rusage
结构体中包含了一系列成员变量,用于存储不同类型的资源使用情况,例如ru_utime
表示用户CPU时间,ru_stime
表示系统CPU时间,ru_maxrss
表示最大常驻集大小等等。
关于驻留集:当一个进程在运行的时候,操作系统不会一次性加载进程的所有数据到内存,只会加载一部分正在用,以及预期要用的数据。其他数据可能存储在虚拟内存,交换区和硬盘文件系统上。被加载到内存的部分就是resident set。
调用getrusage
函数后,如果返回值为0,则表示成功获取资源使用情况。
通过访问struct rusage
结构体中的成员变量来获取所需的资源使用情况信息。
可使用字段
ru_utime
这是在用户模式下执行所花费的总时间,以 timeval 结构表示(秒加微秒)。
ru_stime
这是在内核模式下执行所花费的总时间,以 timeval 结构表示(秒加微秒)。
ru_maxrss
(since Linux 2.6.32)
使用的最大驻留集大小(以千字节为单位)。 对于 RUSAGE_CHILDREN,这是最大子进程的常驻集大小,而不是进程树的最大常驻集大小。
关于驻留集:当一个进程在运行的时候,操作系统不会一次性加载进程的所有数据到内存,只会加载一部分正在用,以及预期要用的数据。其他数据可能存储在虚拟内存,交换区和硬盘文件系统上。被加载到内存的部分就是resident set。
ru_minflt
The number of page faults serviced without any I/O activity; here I/O activity is avoided by “reclaiming” a page frame from the list of pages awaiting reallocation.
在没有任何 I/O 活动的情况下服务的页面错误数; 这里通过从等待重新分配的页面列表中“回收”一个页面框架来避免 I/O 活动。
ru_majflt
The number of page faults serviced that required I/O activity.
需要 I/O 活动的情况下,服务发生页面错误的次数。
ru_inblock
(since Linux 2.6.22)
文件系统必须执行输入的次数。
The number of times the filesystem had to perform input.
ru_oublock
(since Linux 2.6.22)
文件系统必须执行输出的次数。
The number of times the filesystem had to perform output.
ru_nvcsw
(since Linux 2.6)
由于进程在其时间片完成之前自愿放弃处理器(通常是为了等待资源可用)而导致上下文切换的次数。
The number of times a context switch resulted due to a process voluntarily giving up the processor before its time slice was completed (usually to await availability of a resource).
ru_nivcsw
(since Linux 2.6)
由于更高优先级的进程变得可运行或当前进程超过其时间片而导致上下文切换的次数。
The number of times a context switch resulted due to a higher priority process becoming runnable or because the current process exceeded its time slice.
测试情况
代码1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
int main() {
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
printf("Before allocating memory:Memory usage: %ld KB\n", usage.ru_maxrss);
sleep(1);
int *arr =malloc(sizeof(int)*1024*8*1024);
getrusage(RUSAGE_SELF, &usage);
printf("After allocating memory:Memory usage: %ld KB\n", usage.ru_maxrss);
sleep(1);
free(arr);
printf("After release:Memory usage: %ld KB\n", usage.ru_maxrss);
return 0;
}
测试结果
Before allocating memory: Memory usage: 2592 KB
After allocating memory: Memory usage: 2592 KB
After release:Memory usage: 2592 KB