QTcpSocket memory leaking

别说谁变了你拦得住时间么 提交于 2019-12-11 11:23:06

问题


I have a client-server application setup using QTcpServer and QTcpSockets and seem to have some huge memory leaks. I'm wondering if the problem is in my use of Qt's sockets because I have just set up a simple test application and after sending 250,000,000 messages in a loop my client rises up to 75 meg. It seems that if I have several million messages, I see 300+ MB of memory used in my client.

This doesn't seem right to me, as I keep sending messages the memory just keeps on rising!

So should I expect my app to constantly rise in memory given the following code on a connected socket. If this socket is left open I'm going to quickly run out of memory. Am I missing something?

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

回答1:


This is expected because you are potentially buffering a large amount of data. This is an async API due to the Qt event loop, so you should wait for the write when the program is ready for that.

You can use the void QIODevice::bytesWritten(qint64 bytes) [signal] signal to continue the writing. If you use the async API this way, you will avoid the large memory consumption.




回答2:


The socket is an internally buffered QIODevice, and whatever you've written to it gets buffered until the network stack can actually send it out. What you see is expected behavior. The write() is not a blocking operation, and anyway you should never ever do blocking operations in your GUI thread, unless you think users really enjoy applications with dead user interface.

Perhaps you want to put your writing in a slot that gets informed of the socket's progress? The sockets are all QIODevice. Look there for the useful signals, bytesWritten() for example. It's customary to defer writing unless the value returned by bytesToWrite() is below a set threshold. Your writing slot could begin like so:

// more than 2 pages worth of stuff still to send, we abstain
if (socket->bytesToWrite() > 1<<13) return; 

Nitpick: The toStdString() is completely grauituous. You should be using:

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

Never mind that for such testing, you can trivially create an array of bytes without using a string at all:

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


来源:https://stackoverflow.com/questions/19164770/qtcpsocket-memory-leaking

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!