我如何找到为什么虚拟内存占用量随此守护程序不断增长的原因?

时间:2018-10-03 01:31:15

标签: c++ multithreading valgrind address-sanitizer massif

我创建了一个守护程序,将其用作Cassandra数据库的代理。我称它为snapdbproxy是因为它可以替代其他服务器和工具中的CQL命令。

每当我访问该工具时,它都会创建一个新线程,管理各种CQL命令,然后一旦连接断开,便会干净地退出该线程。

看看内存占用量,它增长得非常快(最活跃的系统很快达到了虚拟内存的Gb,并利用了一些不断增长的交换内存。)启动时,它约为300Mb。

enter image description here

该软件是用C ++编写的,具有析构函数,RAII,智能指针等,但我仍然进行过验证:

  1. 使用-fsanitizer=address(我在Linux下使用g ++)并且没有泄漏(好吧,不足300个字节...因为我找不到如何摆脱一些Cryto的方法) OpenSSL创建的缓冲区)

  2. 使用valgrind massif表示我在初始化时使用4.7mB,然后在4mB以下进行中(我在1h内运行相同的代码并获得了相同的结果!)

ms_print的一些输出(我删除了堆栈,因为全为零)。

-------------------------------------------------------------------
  n        time(i)         total(B)   useful-heap(B) extra-heap(B)
-------------------------------------------------------------------

  0              0                0                0             0
  1     78,110,172        4,663,704        4,275,532       388,172
  2    172,552,798        3,600,840        3,369,538       231,302
  3    269,590,806        3,611,600        3,379,648       231,952
  4    350,518,548        3,655,208        3,420,483       234,725
  5    425,873,410        3,653,856        3,419,390       234,466
...
 67  4,257,283,952        3,693,160        3,459,545       233,615
 68  4,302,665,173        3,694,624        3,460,827       233,797
 69  4,348,046,440        3,693,728        3,457,524       236,204
 70  4,393,427,319        3,685,064        3,449,697       235,367
 71  4,438,812,133        3,698,352        3,461,918       236,434

正如我们所看到的,在一小时后,其他各种守护程序进行了多次访问(至少100次访问),valgrind告诉我,我仅使用了大约4mB的内存。我尝试了两次,以为第一次尝试可能失败了。结果相同。

所以...我或多或少都没有主意。为什么我的进程在虚拟内存方面会继续增长,即使在每个线程退出时正确释放了所有内容(如massif输出所示)以及整个进程(如-fsanitizer=address所示(好的,我“这里没有显示消毒剂的输出,但是请相信我,它的大小小于300字节。不是泄漏的Gb。)


一段时间后,当我查看内存(虚拟内存)状态时,将显示watch命令的输出:

Every 1.0s: grep ^Vm /proc/1773/status       Tue Oct  2 21:36:42 2018

VmPeak:  1124060 kB   <-- starts at under 300 Mb...
VmSize:  1124060 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:    108776 kB
VmRSS:    108776 kB
VmData:   963920 kB   <-- this tags along
VmStk:       132 kB
VmExe:      1936 kB
VmLib:     65396 kB
VmPTE:       888 kB   <-- this increases too (necessary to handle the large Vm)
VmPMD:        20 kB
VmSwap:        0 kB

每运行其他守护程序(大约每5分钟运行一次),VmPeakVmSizeVmData都会增加

但是,内存(malloc / free)没有改变。我现在正在登录sbrk(0)(基于1201ProgramAlarm的评论的一个主意-我对他的评论的第一部分的解释),并且该地址保持不变:

sbrk() = 0x4228000

如phd所建议,随着时间的推移,我查看了/proc/<pid>/maps的内容。这是一两个增量。不幸的是,我没有被告知是什么创建了这些缓冲区。我唯一能想到的就是我的线程...(即堆栈和用于线程状态的少量空间)

--- a1  2018-10-02 21:50:21.887583577 -0700
+++ a2  2018-10-02 21:52:04.823169545 -0700
@@ -522,6 +522,10 @@
 59dd0000-5a5d0000 rw-p 00000000 00:00 0 
 5a5d0000-5a5d1000 ---p 00000000 00:00 0 
 5a5d1000-5add1000 rw-p 00000000 00:00 0 
+5add1000-5add2000 ---p 00000000 00:00 0 
+5add2000-5b5d2000 rw-p 00000000 00:00 0 
+5b5d2000-5b5d3000 ---p 00000000 00:00 0 
+5b5d3000-5bdd3000 rw-p 00000000 00:00 0 
 802001000-802b8c000 rwxp 00000000 00:00 0 
 802b8c000-802b8e000 ---p 00000000 00:00 0 
 802b8e000-802c8e000 rwxp 00000000 00:00 0 

哦,是的!我最新的变化是从分离线程到加入……实际上根本不加入线程。现在通过正确的连接进行测试...,它的工作原理正确!我的!坏人!

0 个答案:

没有答案