ACE动态库在windows程序中通过LoadLibrary和FreeLibrary反复加载和卸载后,发现内存和句柄上涨严重,查看动态库的dllmain函数,发现未调用到ace初始化方法ACE::init(),因此加载动态库后,显式调用init,卸载前显式fini,内存和句柄果然就没有涨了,但出现了一个新问题,在加载到500多次以后,出现了动态库文件无法打开错误,通过更新ACE最新的6.2.0版本的库,发现问题依然存在!
前面成功的500多次加载和卸载ace库,都未看到句柄或者内存泄露现象,突然出现不能加载,问题开始有点难以理解了。
查看ace初始化函数的实现代码,包含了对对象管理器单例对象的初始化操作:
int
ACE::init (void)
{
// Don't use ACE_TRACE, because Object_Manager might not have been
// instantiated yet.
// ACE_TRACE ("ACE::init");
++ACE::init_fini_count_;
return ACE_Object_Manager::instance ()->init ();
}
到ACE_Object_Manager::init里注释代码,也未果;由于每次都是在500多次加载后失败,因此尝试init后不调用fini,果然到100多次后问题就出现了,看来还是和资源未释放完全相关的。在退出函数fini里注释代码,希望能定位到影响问题出现概率的那行代码从而找到相关的资源信息,把fini函数如下代码注释后,问题概率加大:
// Close the main thread's TSS, including its Log_Msg instance.
ACE_OS::cleanup_tss (1 /* main thread */);
ACEd.dll!ACE_OS::thr_keycreate_native(unsigned long * key=0x00ab6220, void (void *)* dest=0x00000000) Line 4791 C++
ACEd.dll!ACE_OS::thr_keycreate(unsigned long * key=0x00ab6220, void (void *)* dest=0x00000000) Line 4835 + 0xd bytes C++
ACEd.dll!ACE_Thread::keycreate(unsigned long * keyp=0x00ab6220, void (void *)* destructor=0x00000000) Line 23 + 0xd bytes C++
ACEd.dll!ACE_Threading_Helper::ACE_Threading_Helper() Line 43 + 0xb bytes C++
ACEd.dll!ACE_Service_Config::ACE_Service_Config(bool ignore_static_svcs=true, unsigned int size=1024, int signum=0) Line 372 + 0x6d bytes C++
> ACEd.dll!ACE_Singleton::ACE_Singleton() Line 15 C++
ACEd.dll!ACE_Unmanaged_Singleton::ACE_Unmanaged_Singleton() Line 19 + 0x16 bytes C++
ACEd.dll!ACE_Unmanaged_Singleton::instance() Line 184 + 0x27 bytes C++
ACEd.dll!ACE_Service_Config::singleton() Line 327 C++
ACEd.dll!ACE_Service_Config::current() Line 424 + 0x5 bytes C++
ACEd.dll!ACE_Service_Config::instance() Line 87 C++
ACEd.dll!ACE_Service_Config::insert(ACE_Static_Svc_Descriptor * stsd=0x102609bc) Line 332 + 0x9 bytes C++
ACEd.dll!ACE_Static_Svc_ACE_Naming_Context::ACE_Static_Svc_ACE_Naming_Context() Line 650 + 0x18 bytes C++
ACEd.dll!`dynamic initializer for 'ace_static_svc_ACE_Naming_Context''() Line 650 + 0xd bytes C++
以及:
ACEd.dll!ACE_OS::thr_keycreate_native(unsigned long * key=0x00ab9648, void (void *)* dest=0x1000b2ad) Line 4791 C++
ACEd.dll!ACE_OS::thr_keycreate(unsigned long * key=0x00ab9648, void (void *)* dest=0x1000b2ad) Line 4835 + 0xd bytes C++
> ACEd.dll!ACE_TSS_Cleanup::tss_keys() Line 993 + 0x14 bytes C++
ACEd.dll!ACE_TSS_Cleanup::thread_use_key(unsigned long key=7) Line 941 + 0xc bytes C++
ACEd.dll!ACE_OS::thr_setspecific(unsigned long key=7, void * data=0x00ab9688) Line 5049 C++
ACEd.dll!ACE_Thread::setspecific(unsigned long key=7, void * value=0x00ab9688) Line 42 + 0xd bytes C++
ACEd.dll!ACE_Threading_Helper::set(void * p=0x00ab9688) Line 54 + 0xf bytes C++
ACEd.dll!ACE_Service_Config::ACE_Service_Config(bool ignore_static_svcs=true, unsigned int size=1024, int signum=0) Line 386 C++
ACEd.dll!ACE_Singleton::ACE_Singleton() Line 15 C++
ACEd.dll!ACE_Unmanaged_Singleton::ACE_Unmanaged_Singleton() Line 19 + 0x16 bytes C++
ACEd.dll!ACE_Unmanaged_Singleton::instance() Line 184 + 0x27 bytes C++
ACEd.dll!ACE_Service_Config::singleton() Line 327 C++
ACEd.dll!ACE_Service_Config::current() Line 424 + 0x5 bytes C++
ACEd.dll!ACE_Service_Config::instance() Line 87 C++
ACEd.dll!ACE_Service_Config::insert(ACE_Static_Svc_Descriptor * stsd=0x102609bc) Line 332 + 0x9 bytes C++
ACEd.dll!ACE_Static_Svc_ACE_Naming_Context::ACE_Static_Svc_ACE_Naming_Context() Line 650 + 0x18 bytes C++
ACEd.dll!`dynamic initializer for 'ace_static_svc_ACE_Naming_Context''() Line 650 + 0xd bytes C++
msvcr90d.dll!0045c02c()
ACE_TSS_Keys *
ACE_TSS_Cleanup::tss_keys ()
{
if (this->in_use_ == ACE_OS::NULL_key)
{
ACE_TSS_CLEANUP_GUARD
// Double-check;
if (in_use_ == ACE_OS::NULL_key)
{
// Initialize in_use_ with a new key.
if (ACE_OS::thr_keycreate (&in_use_,
&ACE_TSS_Cleanup_keys_destroyer))
{
ACE_ASSERT (false);
return 0; // Major problems, this should *never* happen!
}
}
}
ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void)
{
free_key(in_use_);
in_use_ = 0;
}