Proactor模式下ACE_Asynch_Connector内存泄露问题
void CProactorClient::Release(){
if (this->handle () != ACE_INVALID_HANDLE)
{
this->reader_.cancel();
this->writer_.cancel();
ACE_OS::shutdown(this->handle_, ACE_SHUTDOWN_BOTH);
ACE_OS::closesocket (this->handle ());
this->handle (ACE_INVALID_HANDLE);
delete this;
}
cur_ = NULL;
}
void CProactorClient::open (ACE_HANDLE h, ACE_Message_Block&)
{
if (this->reader_.open (*this, h) != 0 )
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("CProactorClient open reader_")));
delete this;
return;
}
if (this->writer_.open (*this) != 0 )
{
delete this;
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("CProactorClient open write_")));
return;
}
msgblock_ = new ACE_Message_Block(1024*10);
if (this->reader_.read (*msgblock_, msgblock_->space ()) != 0)
{
ACE_TRACE("Begin read fail\n");
return;
}
ACE_TRACE("Begin open OK \n");
TRACE("Begin client open OK \n");
}
void CProactorClient::handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
if (!result.success () || result.bytes_transferred () == 0)
{
ACE_TRACE("Client Close. \r\n");
TRACE("Client Close. \r\n");
this->Release();
return;
}
msgblock_->reset();
if (this->reader_.read (*msgblock_, msgblock_->space ()) != 0)
{
ACE_TRACE("read data failed!");
TRACE("read data failed!\r\n");
}
}
void CProactorClient::handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block ();
mb.release();
}
int CProactorClient::WriteDate(char *szSendBuf, int nSendCnt)
{
ACE_Message_Block *smb = new ACE_Message_Block(nSendCnt+1);
smb->copy(szSendBuf, nSendCnt);
int nResult = this->writer_.write(*smb, smb->length());
return nResult;
}
Windows XP+VS2008,非常简单的客户端连接处理类,拷贝例子修改下的。
连接服务器时调用:
ACE_Asynch_Connector<CProactorClient> m_curConnector;
ACE_INET_Addr addr(m_nConnectPort, (char*)(LPCSTR)m_strSvrIPAddr);
m_curConnector.open();
m_curConnector.connect(addr);
每次连接成功后,通过任务管理器可以发现内存增长了,但是连接断开后,内存没有减下来,
通过跟踪调试,发现connect()里面会new 不少东西,据说这些东西在完成回调后会释放的,
但是搞不懂在哪里释放。另外可以确认,连接断开的时候delete this被调用。
大虾们出来指点下,看看哪里写出了什么,或者是还需要调用什么来释放连接时产生的内存。
PS: 做过测试,只连接不做任何数据的收发操作,同样会存在内存增长,所以可以确认连接的时候
ACE里面new的内存在delete this之后还是没有被释放的。 用工具查比较理想。
使用boundschecker或者purify. 泄露似乎是你的Message_block没有释放。
if (!result.success () || result.bytes_transferred () == 0)
{
ACE_TRACE("Client Close. \r\n");
TRACE("Client Close. \r\n");
this->Release(); <-这里你的mb没有release()
return;
}
多看看ACE的Test例子,有助于学习。 接受数据只使用一个msgblock_,这个在析构函数中已经释放,不是该变量的问题。 你把
msgblock_ = new ACE_Message_Block(1024*10);
if (this->reader_.read (*msgblock_, msgblock_->space ()) != 0)
{
ACE_TRACE("Begin read fail\n");
return;
}
注释掉,再看内存有无泄漏。若没有就可以基本肯定在handle_read_stream()函数里面的问题。
1.mb->release();未必会释放你的内存,这要看你的Message_block引用计数器的数值。
2.Proactor是异步模式,可能会并行调用你的handle_read_stream(),这里要注意你的内存指针。
页:
[1]