Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何找出代码中创建虚拟内存最多的部分?_C++_Linux_Memory_Malloc - Fatal编程技术网

C++ 如何找出代码中创建虚拟内存最多的部分?

C++ 如何找出代码中创建虚拟内存最多的部分?,c++,linux,memory,malloc,C++,Linux,Memory,Malloc,我有一个启动的程序,在大约5分钟内,进程的虚拟大小约为13千兆次。它运行在Linux上,使用Boost、GNU C++库和各种其他第三方库。p> 5分钟后,大小保持在13 Gig,rss大小稳定在5 Gig左右 我不能只在调试器中运行它,因为在启动时大约启动了30个线程,每个线程都开始运行自己的代码,这些代码执行各种分配。因此,在每个断点处单步执行并检查代码不同部分的虚拟内存是不可行的 我曾想过改变程序,一次启动一个线程,以便更容易跟踪内存分配,但在这样做之前,有什么好的工具吗 Valgrind

我有一个启动的程序,在大约5分钟内,进程的虚拟大小约为13千兆次。它运行在Linux上,使用Boost、GNU C++库和各种其他第三方库。p> 5分钟后,大小保持在13 Gig,rss大小稳定在5 Gig左右

我不能只在调试器中运行它,因为在启动时大约启动了30个线程,每个线程都开始运行自己的代码,这些代码执行各种分配。因此,在每个断点处单步执行并检查代码不同部分的虚拟内存是不可行的

我曾想过改变程序,一次启动一个线程,以便更容易跟踪内存分配,但在这样做之前,有什么好的工具吗

Valgrind相当慢,也许tcmalloc可以提供信息?

我会使用(可能运行一整晚)或者使用

或者,使用文件系统了解(例如,通过
/proc/$pid/statm
&
/proc/$pid/maps
)何时分配了大量内存

最重要的是找到。如果启动后内存没有增长,那么问题就不那么严重了

也许向每个类添加实例计数器会有所帮助(使用原子整数或互斥量来序列化它们)

如果程序的源代码很大(例如一百万行源代码),因此花费几天/几周的时间是值得的,那么定制GCC编译器(例如使用)可能是相关的


a
std::set
minibanchmark 您提到了基于百万行的big
std::set

#include <set>
#include <string>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <time.h>

class MyElem
{
  int _n;
  char _s[16-sizeof(_n)];
public:
  MyElem(int k) :  _n(k)
  {
    snprintf (_s, sizeof(_s), "%d", k);
  };
  ~MyElem()
  {
    _n=0;
    memset(_s, 0, sizeof(_s));
  };
  int n() const
  {
    return _n;
  };
  std::string str() const
  {
    return std::string(_s);
  };
  bool less(const MyElem&x) const
  {
    return _n < x._n;
  };
};

bool operator < (const MyElem& l, const MyElem& r)
{
  return l.less(r);
}

typedef std::set<MyElem> MySet;

void bench (int cnt, MySet& set)
{
  for (long i=0; i<(long)cnt*1024; i++)
    set.insert(MyElem(i));
  time_t now = 0;
  time (&now);
  set.insert (((now) & 0xfffffff) * 100);
}

int main (int argc, char** argv)
{
  MySet s;
  clock_t cstart, cend;
  int c = argc>1?atoi(argv[1]):256;
  if (c<16) c=16;
  printf ("c=%d Kiter\n", c);
  cstart = clock();
  bench (c, s);
  cend = clock();
  int x = getpid();
  char cmdbuf[64];
  snprintf(cmdbuf, sizeof(cmdbuf), "pmap %d", x);
  printf ("running %s\n", cmdbuf);
  fflush (NULL);
  system(cmdbuf);
  putchar('\n');
  printf ("at end c=%d Kiter clockdiff=%.2f millisec = %.f µs/Kiter\n",
          c, (cend-cstart)*1.0e-3, (double)(cend-cstart)/c);
  if (s.find(x) != s.end())
    printf("set has %d\n", x);
  else
    printf("set don't contain %d\n", x);
  return 0;
}    
#包括
#包括
#包括
#包括
#包括
#包括
#包括
MyElem类
{
国际;;
字符[16个大小(_n)];
公众:
迈勒姆(内特k):\n(内特k)
{
snprintf(_s,sizeof(_s),“%d”,k);
};
~MyElem()
{
_n=0;
memset(_s,0,sizeof(_s));
};
int n()常量
{
返回n;
};
std::string str()常量
{
返回std::string(_s);
};
无布尔(常数MyElem&x)常数
{
返回_n如果(C它是什么样的程序?它的大小是多少?你能展示一些源代码吗?什么是第三方库?描述更多你正在使用的程序类型!大部分内存从数据库表读取,并读入std集。它还通过网络从套接字接收数据。我们谈论的是数百万个db行,但13g过多的IMHO。我有其他使用相同库的程序,这些库不读取行,并且内存更好,因此我们认为db读取到集合是问题。我将尝试valgrind并让它运行。我认为您是正确的,std开销不多。我猜可能所有线程同时启动并执行分配是在分割内存y、 在过去,我曾成功地将字符串池用于此数据,因为表中的列经常多次包含相同的字符串。想想员工数据库,如果将字符串用于员工的部门字段,则通常共享该字符串可以节省内存。使用ref计数字符串。