【问题标题】:QTcpSocket memory leakingQTcpSocket 内存泄漏
【发布时间】: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());
    }
}

【问题讨论】:

  • 您如何初始化/分配您的套接字变量?如果可以,请添加更多代码。

标签: c++ qt memory-leaks qtnetwork


【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    • 2019-08-10
    • 2013-06-24
    相关资源
    最近更新 更多