内存与QTcpSocket泄漏(QTcpSocket memory leaking)

2019-10-18 17:30发布

我一直在使用QTcpServer既可与QTcpSockets,似乎有一些巨大的内存泄漏客户端 - 服务器应用程序的设置。 我想知道如果这个问题是在我使用Qt的插座,因为我刚刚建立了一个简单的测试应用程序,并在一个循环我的客户上升到75兆250,000,000发送的消息后。 看来,如果我有几百万的消息,我看到300 + MB的内存在我的客户使用。

这似乎不是我的权利,我不停地发送信息的存储空间只是不断上升!

所以,我应该期待我的应用程序在不断上升内存给出一个连接插座下面的代码。 如果此套接字开着我会很快耗尽内存。 我缺少的东西吗?

if (socket && socket->isOpen())
{
    for(int i = 0; i < 25000000; ++i) {
        QString str = "test";
        socket->write(str.toStdString().c_str());
    }
}

Answer 1:

这是预期的,因为你有可能缓冲了大量的数据。 这是由于Qt的事件循环异步API,所以你应该等待时写的程序做好准备。

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



Answer 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; 

鸡蛋里挑骨头:该toStdString()是完全grauituous。 你应该使用:

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

没关系,对于这样的测试,你可以平凡创建一个字节数组,而无需使用一个字符串都:

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


文章来源: QTcpSocket memory leaking