2013-06-01 135 views
0

我在代碼中遇到了一個問題。C++ Boost :: Thread&Boost :: ASIO內存泄漏

當連接完成時,有10兆RAM會泄漏每個人的連接。

連接工作屬性,並且發送數據包有效。

我不知道哪裏錯了。

工人功能:

void worker(boost::shared_ptr<CConnection> connection) 
{ 
    boost::asio::ip::tcp::socket &socket = *(connection->socket); 
    boost::asio::socket_base::non_blocking_io make_non_blocking(true); 
    socket.io_control(make_non_blocking); 

    while (connection->close == false) { 

    char * buffer = new char[16](); 
    buffer[0] = 16; 
    buffer[4] = 1; 
    buffer[8] = 1; 
    buffer[12] = 1; 

    boost::asio::async_write(socket, boost::asio::buffer(buffer, 16), boost::bind(handle_write, buffer)); 
    connection->close = true; 
    } // while connection not to be closed 
    LOG(INFO, "Connection finished!"); 
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both); 
    socket.close(); 
} 

接受器代碼:

void CCore::handle_accept(const boost::system::error_code& error) 
{ 
    if (error) { 
     // accept failed 
     LOG(ERROR, "Acceptor failed: " << error.message()); 
     return; 
    } 

    LOG(INFO, "Accepted connection from " << this->connection->endpoint.address().to_string() << ":" << this->connection->endpoint.port()); 

    this->connection->thread = boost::shared_ptr<boost::thread>(new boost::thread(worker, this->connection)); 

    this->connection = boost::shared_ptr<CConnection>(new CConnection()); 
    this->connection->master_io_service = this->io_service; 
    this->acceptor->async_accept(*(this->connection->socket), this->connection->endpoint, boost::bind(&CCore::handle_accept, this, boost::asio::placeholders::error)); 
} 

連接定義:

class CConnection { 
    public: 
    CConnection(void); 
    boost::asio::io_service io_service; 
    boost::shared_ptr<boost::asio::ip::tcp::socket> socket; 
    boost::asio::ip::tcp::endpoint endpoint; 
    boost::shared_ptr<boost::thread> thread; 
    boost::asio::io_service *master_io_service; 

    bool close; 
}; 

分組數據在handle_write通過釋放10

感謝您的幫助。

回答

1

根據this page boost :: asio :: buffer不擁有它指向的內存,因此您的new[]漏洞的緩衝區沒有匹配的delete[]

再次,根據該頁面確定其保持活動狀態,然後delete[]之後的責任。

+0

內存在分組數據的句柄寫入中被釋放。 –

1

在工作線程中,你在每個循環中分配內存,但是你永遠不會釋放它。

您可以使用smart pointers,或將指針作爲參數傳遞給異步寫入habndler函數並將其釋放。

+0

在handle_write中釋放內存:delete [] buf; –

+0

@KacperFałat那麼你應該在問題中說明,因爲它不明顯。 –

+0

問題中已更新。 –

1

寫緩衝區的內存管理看起來很好。有CConnectionCConnection::thread之間循環引用:

  • CConnection::thread的壽命取決於CConnection,因爲它是一個成員變量。
  • CConnection的生命期間接依賴於CConnection::thread,因爲CConnection作爲參數綁定爲boost::thread的構造函數。這個參數的生命週期與boost::thread對象的生命週期相關聯,而不是底層線程的執行。

    void CCore::handle_accept(...) 
    { 
        ... 
    
        this->connection->thread = 
        boost::shared_ptr<boost::thread>(new boost::thread(worker, 
                     this->connection)); 
        ... 
    } 
    

卸下循環引用應允許正確的清除。我不清楚這些物體的預期使用壽命,所以我無法提供確切的解決方案。


另外,一些Boost.Asio處理對我來說看起來有點尷尬。它看起來好像混合了同步和異步行爲,這可能很難完成。在這種情況下,可能會在完成之前取消async_write操作。考慮同步workerhandle_write之間的狀態,並在handle_write之內設置關閉狀態。