我今天正在对一组程序进行压力测试。我大幅增加了程序的输入负载,它一开始就工作了,但我有明显的内存泄漏,吸收了内存。唯一的问题是 1)Valgrind
坚持我没有任何泄漏,2)它只会发生高数据包摄取率。
一个可能很疯狂的想法是,由于我的系统缺乏带宽来以数据包传入的速度输出数据包,因此额外的内存可能会流向消息队列,从而迫使传输越来越大的数据缓冲区。显示占用内存的程序正在从 TCP 套接字读取数据并写入命名管道。所以我有三个问题。
对于 TCP/IP 或命名管道,用于存储要分派的数据的内存队列是否可以无限期地增加?
如果队列可以并且确实增长,它是否仍会显示我的程序(从 TCP 读取并输出到命名管道的程序)是内存占用者,或者内存只会显示为系统内存?
有没有一个命令可以用来检查分配给这些队列的内存?我正在运行 Centos
诚然,我真的不认为这是我泄漏的原因,但话又说回来,我真的无法猜测还有什么,所以我不得不问!
答案1
- 一般来说,它是相当有限的。虽然有二(至少)这些缓冲区可以存在的地方:
- 在内核中。肯定是有界限的。我相信 FIFO 是硬编码的,TCP 可以在(和 rmem)中设置
/proc/sys/kernel/tcp_wmem
,并且(在 proc 限制内)使用setsockopt
SO_SNDBUF
/SO_RCVBUF
。有关详细信息,请参阅 tcp(7) 联机帮助页。 - 在你的应用程序中。如果您不直接调用 write 等,则您正在使用的库可能有自己的缓冲区。这些可能是无限的。
- 好的。实际上还有第三个地方,即网卡上的 RAM。如果不焊接,就无法增加到超过某个(相当小的)限制,所以我忽略了这一点。哦,还有一个传输环形缓冲区,供你的网卡DMA出来的。再次强调,固定大小(ethtool 进行调整,如果可能的话)。
- 在内核中。肯定是有界限的。我相信 FIFO 是硬编码的,TCP 可以在(和 rmem)中设置
- 内核显示为系统内存。您的应用程序中的那些将显示为您的应用程序的虚拟大小(和驻留大小等)的一部分
netstat -t
将显示每个 TCP 连接的发送和接收队列的当前大小。对于您图书馆中保存的内容,请检查其文档。
请记住,记忆不是泄露如果你最终释放了它。如果您只是遭受应用程序中不断增长的队列的困扰,那么这并没有泄露。如果您正遭受不断增长的内存碎片的困扰,情况也是如此。