我已经自己解决了这个问题,奖励不会被授予。这个问题是由非GUI线程启动的GUI操作引起的。Qt 4.7:TCP线程,数据传输导致内存泄漏
的Qt 4.7 OSX 10.6.8
有一个在应用了大量的代码,但不参与什么事情一大堆。
数据内存泄漏发生在单个连接的上下文中,该连接在单个Qt线程中打开,读取,写入和关闭。我使用一个固定的存储器对象(PMSG),以保持我的消息,然后将它们发送到所述外部设备是这样的:
m_pTcpSocket->write((char*)pMsg->Buf8, (qint64)pMsg->GetLength());
BUF8是一个2048字节的静态阵列。 GetLength是消息的前16位,与0xFF对应,因此0到255之间的数字应该返回4,这些消息总是在我的诊断中出现。这两个操作都由自己的互斥体(意思是不同的互斥体)包围。消息长度通常为4个字节。这些消息可靠地到达我们有线局域网中其他地方的接收设备;它们在到达时是正确的,并且设备只针对这些消息进行适当的ACK响应。之后我尝试添加一个调用flush()的方法;没有帮助(也不应该有任何冲洗,但...)我不知道泄漏是在写()。
发送这些消息反过来导致我收到来自设备的ACK消息。我读它是这样的:(当然)
if (m_pTcpSocket->waitForReadyRead(100))
{
while ((bytesavailable = m_pTcpSocket->bytesAvailable()))
{
m_pTcpSocket->read(RBuf, bytesavailable);
AssembleMsg(Buf, bytesavailable); // state machine empties Buf
}
}
循环后,信息bytesAvailable为零BUF是一个无符号字符指针2048无符号字符的静态阵列在其被接收的数据的各部分之后,我运行一个组装消息的简单状态机。消息长度为4.消息按预期接收和汇编,不进行内存分配,也不声明对象。这两个操作都被自己的互斥体所包围(意思是不同的互斥体,所以它们不能在rx和tx之间进行交互)。一旦消息汇编完成,它所做的就是重置一个计数器,将计时器设置为下一个保持消息的延迟如果没有它们,设备将断开连接。)通过在waitforreadyread(100)之后进行计数来累积延迟,只要设备不向该端口发送任何内容(这是典型行为),该延迟就会计算该长度的间隔。这样就不需要定时器。计时工作正常。只要消息到达,或者至少在100毫秒内读取消息。他们不累积。所以我认为读取缓冲区不会变大(呃)。但是......我不知道。东西越来越大!
这就是阅读。但是我不知道泄漏是否在read()中。
但它必须是一个或另一个。如果我不发送这些消息(这意味着我也没有收到ACK消息),那么就没有泄漏。应用程序中任何地方都没有其他更改这是它启动的模式,没有其他活动正在进行,我只是保持连接打开,所以当它运行收音机的时候,端口就准备好了。
这两个都在同一个线程中运行,并且它们都运行在同一个套接字上。线程持续运行,并且相同的套接字保持打开(实际上几个小时)。所以它不是套接字对象删除问题。
由于某些品牌的SDR收音机需要在接收操作期间保持活动状态,这意味着该应用程序坐在那里,并且在接收到时像坐在那里等待时一样疯狂地咀嚼内存。
我在大约12小时内损失了大约250兆字节,大概在100k以下。我可以一次观看应用程序内存增加1MB,大约每秒一次。
我已经搜索了很多,我能找到的所有讨论都没有通过多个连接删除tcp对象,这在这里绝对不是问题。
我真的很茫然。问题与我在线程中使用套接字有关吗?应用程序(一个非常复杂的软件定义无线电应用程序)可以运行10到16个线程,具体取决于它在做什么;我在自己的线程中运行数据传输,因此它们不会受到与主事件循环相关的任何事情的影响。
我试过valgrind,但它试图启动它之前终止了应用程序,在这之前就开始了。我不认为它喜欢线程或其他东西。或者它可能是10.6.8,但无论如何,这是行不通的。无论如何,Qt 4.7并没有整合它。我知道没有办法跟踪应用程序中的内存使用情况,这样我就可以包装每个发送和接收,并至少弄清楚哪一个(或两者?)负责。
***编辑:通过改变keepalive消息的速率,我直接改变了内存泄漏的速度,正如我上面所说的,如果keepalive没有被发送,所有。
这就是我所能想到的告诉你的人;任何建议都欢迎,任何有关Qt中的TCP怪癖的照明都会受到欢迎,基本上都是如此。我已经花了很多时间在这个问题上,并且在这个关头我只是受到了限制。
你写了很多按键,似乎表明你可以产生一个很好的短[MCVE](http://stackoverflow.com/help/mcve)来消除所有的疑问,但是你是否真的试过在单线程[MCVE](http://stackoverflow.com/help/mcve)? – Sebivor 2015-12-30 04:15:01
我看到五个函数调用,我们没有代码(4用'm_pTcpSocket'和'AssembleMsg')。其中任何一个都可能是罪魁祸首。你可以添加这些代码吗? – 1201ProgramAlarm 2015-12-30 04:40:20
人们,这个问题并没有在一个简短的例子中重现。这可能是我在这之外做的事情;但我们正在谈论大量的代码行 - 该应用程序大约有55k行代码,不包括Qt生成的任何内容。而且有很多来回TCP和传入的UDP。如果这里不太明显,其他地方就不那么明显了。它当然可以在其他地方 - 我认为我做对了,我只是没有想法。我觉得提供赏金有点不好,我想我可能会浪费人们的时间。但我没有办法撤回它。 – fyngyrz 2015-12-30 06:39:00