如何在运行时跟踪所使用的总内存量?

17 浏览
0 Comments

如何在运行时跟踪所使用的总内存量?

我需要在程序运行时获取我的程序的内存使用情况(VIRT和RES)并显示出来。\n我目前尝试了以下方法:\n使用getrusage(http://linux.die.net/man/2/getrusage)函数\n

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

\n但我始终得到的结果都是0。

0
0 Comments

问题的原因是之前的方法并不能准确地跟踪运行时使用的总内存量。解决方法是通过使用libproc库来获取进程的信息,并使用该信息来获取内存使用量。

首先需要安装libproc库,然后使用下面的代码来获取内存使用量:

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

编译命令为“gcc -o getrusage getrusage.c -lproc”。

这种方法在Ubuntu下测试通过,需要安装libproc-dev包。使用“usage.vm_data”字段可以获得接近所需的内存使用量。可用的内存统计选项在“/usr/include/proc/readproc.h”中有文档记录。我尝试过的选项似乎都是以字节为单位,而不是页面数。我不认为我的进程使用了4600万个页面。说这种方法在Linux下不起作用的评论似乎是不正确的。

正确的链接器命令是“-lprocps”。

这个方法非常有效,应该被接受为答案!

0
0 Comments

如何在运行时跟踪内存使用总量?

问题的原因:用户想要在运行时跟踪内存使用的总量。

解决方法:使用下面提供的代码来获取进程的常驻集大小(物理内存使用)。代码包含了不同操作系统的实现。

#include 
#include 
size_t getCurrentRSS( )
{
    struct rusage rusage;
    getrusage( RUSAGE_SELF, &rusage );
    return (size_t)(rusage.ru_maxrss * 1024L);
}

在使用上述代码时,用户可以调用`getCurrentRSS()`函数获取当前的常驻集大小。这个函数将返回以字节为单位的物理内存使用量。

用户还可以使用`getPeakRSS()`函数来获取峰值常驻集大小。该函数将返回已使用的最大物理内存量。

用户可以根据需要在代码中添加`#pragma comment(lib, "psapi.lib")`,将其放在`#if defined(_WIN32)`的范围内。这个指令是为了在使用Microsoft编译器的Windows环境下编译代码,以避免出现编译错误。

需要注意的是,如果用户使用的是Windows操作系统但不是Microsoft编译器,那么这个指令会导致编译器失败。

另外,这段代码使用了`getrusage`函数中的`rusage::ru_maxrss`来获取物理内存使用量。但是有用户报告说这个函数在她的系统上不起作用。

更多讨论和相关的函数可以在原网页上找到。原网页还提供了一个获取系统物理内存大小的函数。

0
0 Comments

如何在运行时跟踪内存总使用量?

在Linux上,我从未找到一个ioctl()的解决方案。对于我们的应用程序,我们编写了一个基于读取/proc/pid文件的通用实用程序例程。这些文件中有一些给出了不同的结果。这是我们最终选择的一个(问题标记为C++,我们使用C++构造处理I/O,但如果需要,它应该很容易适应C I/O例程):

#include 
#include 
#include 
#include 
#include 
//////////////////////////////////////////////////////////////////////////////
//
// process_mem_usage(double &, double &) - 通过引用获取两个double,
// 尝试读取进程虚拟内存大小和常驻内存集大小的系统相关数据,并以KB为单位返回结果。
//
// 失败时,返回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;
   ifstream stat_stream("/proc/self/stat",ios_base::in);
   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;
   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; // 不关心其余部分
   stat_stream.close();
   long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024;
   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;
}

关于不同*nix平台下/proc/self/stat结构的保证,你有什么保证?...我不确定,但如果有的话,那将很好。

好吧,多年来我主要使用Solaris、HP-UX和Linux。/proc/self/stat似乎是Linux特有的。上面的程序的原始版本在Solaris上有#if块,因为它有所不同。

我假设OP只关心Linux,根据问题标记,读取/proc将是你能得到的最好的结果。在Solaris上,您还可以通过kstat获取有关各种信息(尽管它通常会复制您可以通过其他方式获取的信息)。

我只是迟到了10年,但您介意告诉我为什么除以1024.0而不是1024吗?

'river',抱歉,但正如你所说,多年过去了。如果我有任何原因,那已经失去了(我没有通过注释将特殊选择记录下来,我让大家失望了)。我唯一的辩解是,在这种情况下,1024.0可以表示1024而不会失去精度...

关于`为什么是1024.0?` - 这告诉编译器首先将其转换为double,然后进行除法以获得double结果。另一种选择是`vm_usage = vsize / 1024;`,它会首先执行除法(可能会丢失精度),然后转换为double。

0