当前进程的内存使用情况在C中
问题:在C语言中如何获取当前进程的内存使用情况,以及如何解决该问题。
原因:在Linux上,getrusage()函数的内存跟踪功能几乎无用,所以读取/proc/
解决方法:
typedef struct { unsigned long size,resident,share,text,lib,data,dt; } statm_t; void read_off_memory_status(statm_t& result) { unsigned long dummy; const char* statm_path = "/proc/self/statm"; FILE *f = fopen(statm_path,"r"); if(!f){ perror(statm_path); abort(); } if(7 != fscanf(f,"%ld %ld %ld %ld %ld %ld %ld", &result.size,&result.resident,&result.share,&result.text,&result.lib,&result.data,&result.dt)) { perror(statm_path); abort(); } fclose(f); }
根据proc(5)手册页的介绍,/proc/[pid]/statm文件提供了关于内存使用的信息,以页面为单位进行测量。其中各列的含义如下:
- size:程序的总大小(与/proc/[pid]/status中的VmSize相同)
- resident:当前驻留集大小(与/proc/[pid]/status中的VmRSS相同)
- share:共享页面数量(来自共享映射)
- text:代码段
- lib:库(在Linux 2.6中未使用)
- data:数据+堆栈
- dt:脏页面(在Linux 2.6中未使用)
该方法的问题在于使用“以页面为单位”进行测量。如果进程使用了三个4kB页面、两个2MB页面和一个1GB页面,它会报告使用了6个页面。从技术上讲是正确的,但对于推断以字节为单位的驻留集大小来说毫无用处。
根据man proc文档,/proc/[pid]/status提供了/proc/[pid]/stat和/proc/[pid]/statm中的大部分信息。同时,ps命令也使用了stat文件。这意味着/proc/self/status和ps命令本身也存在同样的问题。您能否引用一些证据来证明单个进程可以具有多个不同大小的页面?谢谢!
回答者:我只能引用我自己使用手动巨页+常规页的经验。
谢谢,我之前不知道有mmap的MAP_HUGE*参数,这令人沮丧。
在C语言中可以使用&符号吗?我以为那是C++的特性,不是吗?我的意思是,该函数应该接受一个statm_t *result指针。我有什么遗漏吗?
回答者:&x是原始的C语言写法,表示“指向变量x的地址”。在C++中,同样的字符用于类型声明,表示引用。
问题:如何在C语言中获取当前进程的内存使用情况?
原因:在C语言中,要获取当前进程的内存使用情况,可以通过打开/proc文件系统中的文件来实现。使用"/proc/self/status"路径可以获取当前进程的状态信息,而"/proc/self/stat"路径可以获取当前进程的统计信息。
解决方法:可以通过以下代码来获取当前进程的内存使用情况:
FILE* status = fopen( "/proc/self/status", "r" );
然后,需要解析文件以提取所需的信息。另外,可以尝试解析"/proc/self/stat"文件,该文件只包含数字而没有标签,据man proc文档所述,该文件被ps命令使用。还可以尝试解析"statm"文件,它是用于内存的stat子集。但是需要注意,对于大页面,这些方法可能是错误的。因此,需要根据具体情况进行测试和验证。
参考链接:
- [stackoverflow.com/a/7212248/895245](https://stackoverflow.com/a/7212248/895245)
- [stackoverflow.com/questions/1558402/…](https://stackoverflow.com/questions/1558402/7212248?noredirect=1#comment101785466_7212248)
当前进程的内存使用情况是通过getrusage
库函数返回的一个结构体来获取的。该结构体包含了关于当前进程的大量数据,其中包括以下三个字段:
long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */
然而,最新的Linux文档对这三个字段的说明是:
(未维护)该字段在Linux上当前未使用
然后,该手册对此进行了定义:
并非所有字段都是完整的;内核会将未维护的字段设为零。(未维护的字段是为了与其他系统兼容,并且因为它们有一天可能在Linux上得到支持。)
请参阅getrusage(2)
不幸的是,我的内核(Ubuntu Hardy)不支持ru_idrss和ru_isrss数据:linux.die.net/man/2/getrusage
不幸的是,在我的内核(Debian Wheezy)上,所有数据都显示为0。