如何在运行时获得内存使用情况在C + +?

我需要得到我的程序运行时的MEM使用VIRT和RES,并显示它们。

我到目前为止的尝试:

getrusage( http://linux.die.net/man/2/getrusage )

int who = RUSAGE_SELF; struct rusage usage; int ret; ret=getrusage(who,&usage); cout<<usage.ru_maxrss; 

但我总是得到0。

在Linux上,我从来没有find一个ioctl()解决scheme。 对于我们的应用程序,我们根据读取/ proc / pid中的文件编写了一个通用的实用程序。 有一些这些文件给出不同的结果。 下面是我们解决的问题(这个问题被标记为C ++,我们使用C ++构造来处理I / O,但是如果需要的话,它应该很容易适应C / I子程序):

 #include <unistd.h> #include <ios> #include <iostream> #include <fstream> #include <string> ////////////////////////////////////////////////////////////////////////////// // // process_mem_usage(double &, double &) - takes two doubles by reference, // attempts to read the system-dependent data for a process' virtual memory // size and resident set size, and return the results in KB. // // On failure, returns 0.0, 0.0 void process_mem_usage(double& vm_usage, double& resident_set) { using std::ios_base; using std::ifstream; using std::string; vm_usage = 0.0; resident_set = 0.0; // 'file' stat seems to give the most reliable results // ifstream stat_stream("/proc/self/stat",ios_base::in); // dummy vars for leading entries in stat that we don't care about // string pid, comm, state, ppid, pgrp, session, tty_nr; string tpgid, flags, minflt, cminflt, majflt, cmajflt; string utime, stime, cutime, cstime, priority, nice; string O, itrealvalue, starttime; // the two fields we want // unsigned long vsize; long rss; stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest stat_stream.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; } int main() { using std::cout; using std::endl; double vm, rss; process_mem_usage(vm, rss); cout << "VM: " << vm << "; RSS: " << rss << endl; } 

大卫·罗伯特·纳 多( David Robert Nadeau )在自己的网站上提供了一个很好的自包含多平台C函数来获取进程驻留集大小(物理内存使用)

 /* * Author: David Robert Nadeau * Site: http://NadeauSoftware.com/ * License: Creative Commons Attribution 3.0 Unported License * http://creativecommons.org/licenses/by/3.0/deed.en_US */ #if defined(_WIN32) #include <windows.h> #include <psapi.h> #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) #include <unistd.h> #include <sys/resource.h> #if defined(__APPLE__) && defined(__MACH__) #include <mach/mach.h> #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) #include <fcntl.h> #include <procfs.h> #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) #include <stdio.h> #endif #else #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." #endif /** * Returns the peak (maximum so far) resident set size (physical * memory use) measured in bytes, or zero if the value cannot be * determined on this OS. */ size_t getPeakRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.PeakWorkingSetSize; #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) /* AIX and Solaris ------------------------------------------ */ struct psinfo psinfo; int fd = -1; if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 ) return (size_t)0L; /* Can't open? */ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) ) { close( fd ); return (size_t)0L; /* Can't read? */ } close( fd ); return (size_t)(psinfo.pr_rssize * 1024L); #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) /* BSD, Linux, and OSX -------------------------------------- */ struct rusage rusage; getrusage( RUSAGE_SELF, &rusage ); #if defined(__APPLE__) && defined(__MACH__) return (size_t)rusage.ru_maxrss; #else return (size_t)(rusage.ru_maxrss * 1024L); #endif #else /* Unknown OS ----------------------------------------------- */ return (size_t)0L; /* Unsupported. */ #endif } /** * Returns the current resident set size (physical memory use) measured * in bytes, or zero if the value cannot be determined on this OS. */ size_t getCurrentRSS( ) { #if defined(_WIN32) /* Windows -------------------------------------------------- */ PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.WorkingSetSize; #elif defined(__APPLE__) && defined(__MACH__) /* OSX ------------------------------------------------------ */ struct mach_task_basic_info info; mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount ) != KERN_SUCCESS ) return (size_t)0L; /* Can't access? */ return (size_t)info.resident_size; #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) /* Linux ---------------------------------------------------- */ long rss = 0L; FILE* fp = NULL; if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL ) return (size_t)0L; /* Can't open? */ if ( fscanf( fp, "%*s%ld", &rss ) != 1 ) { fclose( fp ); return (size_t)0L; /* Can't read? */ } fclose( fp ); return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE); #else /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ return (size_t)0L; /* Unsupported. */ #endif } 

用法

 size_t currentSize = getCurrentRSS( ); size_t peakSize = getPeakRSS( ); 

有关更多讨论,请查看网站,还提供了获取系统物理内存大小的function 。

旧:

maxrss指出进程的最大可用内存。 0意味着对这个过程没有任何限制。 您可能需要的是未ru_idrss数据使用情况ru_idrss

新增function:看起来上面并没有实际的工作,因为内核并没有填充大部分的值。 什么工作是从proc获取信息。 而不是自己parsing它,使用libproc(procps的一部分)更容易,如下所示:

 // getrusage.c #include <stdio.h> #include <proc/readproc.h> int main() { struct proc_t usage; look_up_our_self(&usage); printf("usage: %lu\n", usage.vsize); } 

编译“ gcc -o getrusage getrusage.c -lproc

在linux上,如果你可以承担运行时间的成本(用于debugging),你可以使用valgrind和massif工具:

http://valgrind.org/docs/manual/ms-manual.html

这是重量很重,但非常有用。

现有的答案是更好的如何获得正确的价值,但我至less可以解释为什么getrusage不适合你。

男人2 getrusage:

上述结构[rusage]取自BSD 4.3 Reno。 在Linux下并不是所有的字段都有意义。 现在(Linux 2.4,2.6)只保留ru_utime,ru_stime,ru_minflt,ru_majflt和ru_nswap等字段。

除了你的方式
您可以调用系统ps命令并从输出中获取内存使用情况。
或从/ proc / pid读取信息(请参阅PIOCPSINFO结构)

唐·韦克菲尔德方法更优雅的方式:

 #include <iostream> #include <fstream> using namespace std; int main(){ int tSize = 0, resident = 0, share = 0; ifstream buffer("/proc/self/statm"); buffer >> tSize >> resident >> share; buffer.close(); long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages double rss = resident * page_size_kb; cout << "RSS - " << rss << " kB\n"; double shared_mem = share * page_size_kb; cout << "Shared Memory - " << shared_mem << " kB\n"; cout << "Private Memory - " << rss - shared_mem << "kB\n"; return 0; } 

我正在用其他方式来做到这一点,这听起来很现实。 我所做的是通过getpid()函数得到进程的PID,然后使用/ proc / pid / stat文件。 我相信stat文件的第23列是vmsize(看看Don的post)。 你可以从代码中的任何你需要的文件中读取vmsize。 如果您想知道代码的片段可以使用多less内存,您可以在该代码片段之前和之后一次读取该文件,并且可以相互减去它们。

基于唐W的解决scheme,variables较less。

 void process_mem_usage(double& vm_usage, double& resident_set) { vm_usage = 0.0; resident_set = 0.0; // the two fields we want unsigned long vsize; long rss; { std::string ignore; std::ifstream ifs("/proc/self/stat", std::ios_base::in); ifs >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> ignore >> vsize >> rss; } long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages vm_usage = vsize / 1024.0; resident_set = rss * page_size_kb; } 

我正在寻找一个Linux应用程序来测量使用的最大内存。 valgrind是一个很好的工具,但给我比我想要的更多的信息。 tstime似乎是我能find的最好的工具。 它测量“高水位”内存使用情况(RSS和虚拟)。 看到这个答案 。