glen_dai
发表于 2008-8-7 14:47:22
谢谢楼上的讲解。 result.message_block()就是mReadMsgBlock,我在Reset里回收的。
void ClientHandler::Reset()
{
MsgBlockManagerSingleton::instance()->ReleaseMsgBlock(mReadMsgBlock);
mReadMsgBlock = NULL;
ACE_OS::shutdown(this->handle(), ACE_SHUTDOWN_BOTH);
ACE_OS::closesocket(this->handle());
this->handle(ACE_INVALID_HANDLE);
}
wishel
发表于 2008-8-7 17:12:28
问题是你在release该handler的时候没有调用该reset。(没看到你的handler manager的程序,猜的)
关于pool的是我的个人看法,大家多探讨吧。
glen_dai
发表于 2008-8-7 17:19:19
调用了。。。wishel兄如果有空帮我调试下那个程序:handshake用浏览器直接开链接,应该能进的
我想的是如果重复new,delete的话会产生内存碎片。
[ 本帖最后由 glen_dai 于 2008-8-7 17:22 编辑 ]
wishel
发表于 2008-8-7 22:00:36
汗。。太复杂了,好像把所有能用到的framework和pattern全用上了。我不大会用vc,看了看代码,发现一个小小的问题,根内存泄漏无关,就是ClientHandler的mWriter没有用上。
wishel
发表于 2008-8-7 22:41:25
但是看你的另一个帖子里的Visual Leak Detector的报错信息,很奇怪
---------- Block 14186 at 0x01DACBD8: 4 bytes ----------
Call Stack:
f:\rtm\vctools\crt_bld\self_x86\crt\src\newopnt.cpp (18): operator new
d:\vendor\ace_wrappers\ace\asynch_io.cpp (1059): ACE_Handler::ACE_Handler
d:\vendor\ace_wrappers\ace\asynch_acceptor.cpp (36): ACE_Asynch_Acceptor<ClientHandler>::ACE_Asynch_Acceptor<ClientHandler>
f:\test\aceservertest\clientacceptor.cpp (8): ClientAcceptor::ClientAcceptor
f:\test\aceservertest\main.cpp (21): ace_main_i
f:\test\aceservertest\main.cpp (13): ACE_Main::run_i
d:\vendor\ace_wrappers\ace\os_main.cpp (85): ACE_Main_Base::run
f:\test\aceservertest\main.cpp (13): main
f:\rtm\vctools\crt_bld\self_x86\crt\src\crt0.c (318): __tmainCRTStartup
f:\rtm\vctools\crt_bld\self_x86\crt\src\crt0.c (187): mainCRTStartup
0x7C816FD7 (File and line number not available): RegisterWaitForInputIdle
Data:
好像是说ACE_Asynch_Acceptor用到了operator new,产生新的:ACE_Handler,而其实make_handler()方法已经被override,不会用到operator new。
难道是分析出错?
上面说 d:\vendor\ace_wrappers\ace\asynch_io.cpp (1059): ACE_Handler::ACE_Handler 用到operator new,明显是未被override时候才会调用的。
第1059行的内容: ACE_NEW (p, ACE_Handler::Proxy (this));
wishel
发表于 2008-8-7 22:44:02
你可以测一下是否真的调用到了自己写的那个make_handler(),比如改成打印一行信息然后强行结束程序
glen_dai
发表于 2008-8-8 09:38:30
ACE_Handler::ACE_Handler (void)
: proactor_ (0), handle_ (ACE_INVALID_HANDLE)
{
ACE_Handler::Proxy *p;
ACE_NEW (p, ACE_Handler::Proxy (this)); // asynch_io.cpp (1059) new的是这个东西
this->proxy_.reset (p);
}
make_handler()调的是重写的那个,这个跟踪过的。
mWriter不用他也没什么问题把。。
_coco
发表于 2008-8-8 09:45:53
可以这样测试一下:
开一个连接,分配了哪些内存,断开一个连接,应该释放哪些内存,在这些地方放一个打印信息,看是否执行了释放的操作。还有,请问你是怎么知道服务器并没有释放对方的连接内存资源的? 通过任务管理器来查看?
glen_dai
发表于 2008-8-8 09:53:09
额。。。是跟踪调试的。。。
wishel
发表于 2008-8-8 10:23:47
不用的东西最好注释掉,否则会影响程序的可读性。
如果确实没有用到,那么内存泄漏分析程序就有问题了,其他地方应该也不会调用到这个1059行的new。
另外c++标准并不保证相继new会分配连续的地址空间。虽然当程序刚开始运行时通常是这样,但并不一定。要确保连续空间最好重载operator new,利用placement new指定具体地址。