QTcpSocket 内存泄漏
Posted
技术标签:
【中文标题】QTcpSocket 内存泄漏【英文标题】:QTcpSocket memory leaking 【发布时间】:2013-10-03 16:47:39 【问题描述】:我有一个使用 QTcpServer 和 QTcpSockets 的客户端-服务器应用程序设置,并且似乎有一些巨大的内存泄漏。我想知道问题是否出在我使用 Qt 的套接字上,因为我刚刚设置了一个简单的测试应用程序,并且在循环发送 250,000,000 条消息后,我的客户端上升到 75 兆。似乎如果我有几百万条消息,我会看到我的客户端使用了 300+ MB 的内存。
这对我来说似乎不对,因为我一直在发送消息,内存在不断增加!
因此,鉴于连接套接字上的以下代码,我是否应该期望我的应用程序不断增加内存。如果此套接字保持打开状态,我将很快耗尽内存。我错过了什么吗?
if (socket && socket->isOpen())
for(int i = 0; i < 25000000; ++i)
QString str = "test";
socket->write(str.toStdString().c_str());
【问题讨论】:
您如何初始化/分配您的套接字变量?如果可以,请添加更多代码。 【参考方案1】:这是意料之中的,因为您可能正在缓冲大量数据。由于 Qt 事件循环,这是一个异步 API,因此您应该在程序准备好时等待写入。
您可以使用void QIODevice::bytesWritten(qint64 bytes) [signal]
信号继续写入。如果你这样使用异步 API,你将避免大量的内存消耗。
【讨论】:
我厌倦了按上述方式编写消息,并同意通过缓冲它会增加内存。我没有补充的是,如果我在事件循环运行(并因此发送消息)的情况下等待一段时间,然后发送(或者更确切地说是缓冲)另一束消息,我看到内存增加了一倍。如果我再次等待然后再发送一些,内存会再次上升。随着消息的发送,缓冲区的大小肯定会减小吗? @user1818822:您是否将您的写入操作作为插槽连接到上述信号?那么,它就不会再发生了。 @user1818822:你知道了吗? 我看到了类似的问题,但有多个连接。我删除了所有的 QTcpSocket,但是,当我同时运行 500 个连接时,每次我拍摄另一个 500 个连接时,内存都会不断增加。我不认为我有内存泄漏,我只是认为这是类的缓冲区管理中的一个错误。 我遇到了同样的问题。通过数百个连接,我看到内存显着增加。您是否以某种方式解决了这个问题?【参考方案2】:套接字是一个内部缓冲的QIODevice
,无论您写入它的任何内容都会被缓冲,直到网络堆栈可以真正将其发送出去。你看到的是预期的行为。 write()
不是阻塞操作,无论如何你应该永远在你的 GUI 线程中执行阻塞操作,除非你认为用户真的喜欢用户界面死机的应用程序。
也许你想把你的文章放在一个插槽中,以便获知套接字的进度?套接字都是QIODevice
。在那里寻找有用的信号,例如bytesWritten()
。通常推迟写入,除非bytesToWrite()
返回的值低于设定的阈值。你的写作时间可以这样开始:
// more than 2 pages worth of stuff still to send, we abstain
if (socket->bytesToWrite() > 1<<13) return;
Nitpick:toStdString()
完全没有意义。您应该使用:
socket->write(str.toUtf8().constData());
没关系,对于这样的测试,您可以轻松地创建一个字节数组而不使用字符串:
const QByteArray testData(1000, ' '); // a 1000 spaces
for (int i = 0; i < 100000; ++i) socket->write(testData);
【讨论】:
以上是关于QTcpSocket 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章