2013-10-03 43 views
1

我有一個使用QTcpServer和QTcpSockets的客戶端服務器應用程序設置,似乎有一些巨大的內存泄漏。我想知道是否問題出在我使用Qt的套接字上,因爲我剛剛設置了一個簡單的測試應用程序,並且在循環中發送了250,000,000條消息之後,我的客戶端升至75兆字節。看起來如果我有幾百萬條消息,我會在客戶端看到300+ MB的內存。QTcpSocket內存泄漏

這似乎不是我的權利,我不停地發送信息的存儲空間只是不斷上升!

所以我應該期待我的應用程序在不斷上升內存給出一個連接插座下面的代碼。如果這個插座是開着的,我會快速耗盡內存。我錯過了什麼嗎?

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

你是如何初始化/分配的插座變量?如果可以,添加更多代碼。 – Huy

回答

1

這是預期的,因爲您可能會緩衝大量的數據。由於Qt事件循環,這是一個異步API,所以當程序準備就緒時,您應該等待寫入。

可以使用void QIODevice::bytesWritten(qint64 bytes) [signal]信號繼續寫作。如果以這種方式使用異步API,您將避免大量的內存消耗。

+0

我厭倦瞭如上所述寫入消息,並且同意將它緩存起來會增加內存。我沒有添加的是,如果我等待一段時間,事件循環運行(併發送消息),然後發送(或者說緩衝)另一堆消息,我看到內存增加了一倍。如果我再等一會再發一些,內存就會再次上升。在發送消息時,緩衝區的大小肯定會減少? – user1818822

+0

@ user1818822:您是否將寫作操作作爲插槽連接到上述信號?然後,它不會再發生了。 – lpapp

+0

@ user1818822:你想通了嗎? – lpapp

0

插座是內部緩衝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);