QTcpSocket内存泄漏

时间:2013-10-03 16:47:39

标签: c++ qt memory-leaks qtnetwork

我使用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());
    }
}

2 个答案:

答案 0 :(得分:2)

这是预期的,因为您可能会缓冲大量数据。由于Qt事件循环,这是一个异步API,因此您应该在程序准备就绪时等待写入。

您可以使用void QIODevice::bytesWritten(qint64 bytes) [signal]信号继续写作。如果以这种方式使用异步API,则可以避免大量内存消耗。

答案 1 :(得分:1)

套接字是一个内部缓冲的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()完全是grauituous。你应该使用:

socket->write(str.toUtf8().constData());

不要紧,对于这样的测试,您可以轻松地创建一个字节数组而不使用字符串:

const QByteArray testData(1000, ' '); // a 1000 spaces
for (int i = 0; i < 100000; ++i) socket->write(testData);