2013-06-01 122 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之内设置关闭状态。