1

我有一个使用 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());
    }
}
4

2 回答 2

2

这是意料之中的,因为您可能正在缓冲大量数据。由于 Qt 事件循环,这是一个异步 API,因此您应该在程序准备好时等待写入。

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

于 2013-10-03T19:35:50.163 回答
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()完全是多余的。你应该使用:

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

没关系,对于这样的测试,您可以轻松地创建一个字节数组,而无需使用字符串:

const QByteArray testData(1000, ' '); // a 1000 spaces
for (int i = 0; i < 100000; ++i) socket->write(testData);
于 2013-10-04T14:21:32.540 回答