有没有办法看到每个线程的进程虚拟内存使用情况?

时间:2014-07-30 11:31:21

标签: c++ c linux multithreading memory

我使用的是RHEL 6.3(64位)。 我在我的多线程c / c ++程序中做了一些更改(使用std:map来满足特定需求),现在我的项目的初始虚拟内存使用量已经非常高(大约900米)。我所做的所有更改都在MACRO下进行了保护。

但是在禁用MACRO后,我也看不到我的进程的虚拟内存使用量有任何减少。

所以我有几个问题要问。

  1. 有没有办法找出消耗最大虚拟内存的线程,以便我可以隔离问题?

  2. 为什么在禁用我的进程的宏虚拟内存使用后没有停止?

  3. 32位(RHEL-6.3)上的同一项目占用的虚拟内存非常少(约150米)。 差不多6倍于64位操作系统。为什么呢?

    我使用top命令查看虚拟内存使用情况。

4 个答案:

答案 0 :(得分:1)

您可能应该使用valgrind来搜寻memory leaks。当然,使用调试信息和警告(例如g++ -Wall -g)编译所有程序。使用x86-64上的最新GCC编译器(例如gcc-4.9),您还可以使用地址清理程序(-fsanitize=address

运行(测试)程序时,可以使用pmap(1)查询其地址空间。另见proc(5)。另请尝试htop。在64位系统上对原始程序(无需任何修改)进行基准测试。

我希望您在代码和修改中使用version control system git

根据定义,address spaceprocess中的所有主题都是通用的。认为某些特定线程消耗内存是错误的 - 它是进程本身(即正在运行的程序中的任何线程)。

也许你想为x32 ABI编译。

BTw,每个线程需要一些内存(用于堆栈,TLS等......) - 当然其他线程可以看到,例如如果你在它内部传递一些指针 - 可能更多的是64位而不是32位。你有多少线程? (你可能应该避免使用十几个线程)。

答案 1 :(得分:1)

64位代码指针是8字节而不是具有32位代码的4字节。因此,如果您的代码使用了大量指针,则很容易将堆大小加倍。但这并不能解释6倍的更大。

听起来你想知道你的内存使用情况。谷歌为“内存分析”找到了一个工具。

我通常在自己的代码中进行内存分析

extern void * operator new( size_t, const char *, int );

#if 1
#define MY_NEW() new
#else
#define MY_NEW() new( __FILE__, __LINE__ )
#endif

然后在代码中将'new'的所有使用更改为MY_NEW(),并在要启用内存分析时更改#if。运算符new()调用malloc()并将所有3个参数打印到文件中。然后你创建一个脚本来切片和切块数据你想要什么。为一个文件添加所有分配& __LINE_组合通常是一个很好的起点。此方法不包括库中的内存分配(如STL)。

答案 2 :(得分:1)

使用valgrind --tool=massifhttp://valgrind.org/docs/manual/ms-manual.html)分析程序的内存消耗非常有用,并在修改之前和之后检查其内存消耗情况。

2)首先,既然你说“我使用top命令查看虚拟内存使用情况”,那么测量进程中的所有内存(http://valgrind.org/docs/manual/ms-manual.html#ms-manual.not-measuredvalgrind --tool=massif --pages-as-heap=yes your-program并检入生成内容非常有用报告内存消耗峰值的位置和最大分配的堆栈跟踪。

2)其次,如果在步骤1中您了解问题在堆分配中,请使用valgrind --tool=massif your_program检查您的应用程序,并比较修改前后的进程的内存消耗。

答案 3 :(得分:0)

你可以为你的进程尝试ps命令grep并列出线程 ps -eLF,我无法完全记住按内存使用情况排序。

尝试顶级 - 命令' H'显示线程的选项