如何判断系统中存在Handle为释放导致的内存泄漏
对于内存泄漏,首先要明确的就是并非几次或者几十次测试后内存增加就判定为内存泄漏。WinCE的内存管理中,会存在有些Dirty Memory不会回收,而有些会回收的情况。可以简单的做如下的测试:
- 排除内存碎片的影响
在控制面板中将系统的内存减少到1MB以内,然后重新进行测试,观察是否有内存泄漏的情况发生;
- 系统Loading高导致的内存使用增长
可以测试100或者500次来观察系统内存的变化,如果增长到一定程度之后很长时间内不再增长,可以近似的认为不是内存泄漏;
- 调整系统FilePool/PagePool
Pool的变化会导致内存的变化,可以通过在bib文件中将Targe和Pool的大小配置为一样的值,重新进行测试来判定是否是该因素导致的问题。
好了,做过上面的步骤后,就大概知道是否是一次真正的内存泄漏。
实际的过程中,经常会碰到内存泄漏的问题,导致内存泄漏的原因有很多,最终要的两个方面就是Handle为释放,以及Heap等内存及时的Free。
这里简单的描述一下,如果来debug Handle资源为释放导致的内存泄漏:
一. CELOG
如何使用CELOG来获取Event等Handle是否泄漏
1. 从PC机上拷贝celog.dll and celogflush.exe到Device的Windows目录下,这两个文件应该已经存在与当前工程的Release目录下;
2. 启动CELOG
log -buf 0x100000 0x63 ; 0x100000 means the buffer size, you can change it, 0x63 means flags, means the event you are interested in. If want to know all the zones.....
log -clear ; clear data collected;
详细有关CELOG Zone的配置参照如下链接:
http://msdn.microsoft.com/en-us/library/aa450700.aspx
3. Dump CELOG数据到文件中
log -flush \flashdisk\haha.clg ; clollect the data we have, write to files;
4. 解析CELOG的数据
CELOG的数据是二进制的,需要经过工具转换才能够进行阅读,转换的方法如下:
- 拷贝haha.clg到工程的Release目录下
- 运行readlog – s haha.clg haha_dump.log,然后就可以直接观察haha_dump.log的内容了
例如可以在haha_dump.log看到如下的事件统计信息:
Event counts: CriticalSectionEnter 89 CriticalSectionLeave 89 EventCreate/EventOpen 88 EventSet 1262 EventReset 890 EventPulse 4 EventDelete 87 WaitForMultipleObjects 1793 Sleep 108 CriticalSectionInit 33 CriticalSectionDelete 33 SemaphoreCreate 2 SemaphoreRelease 28 SemaphoreDelete 2 HeapAlloc 1109 HeapRealloc 1 HeapFree 1108 |
5. 通过上面的CriticalSectionInit/ CriticalSectionDelete, EventCreate/EventOpen/ EventDelete,SemaphoreCreate/ SemaphoreDelete是否成对出现,就可以判断出来Event/CS/SEM是否存在Handle为释放的情况。
二.内核对象计数器
在WinCE的Kernel中有一个文件Shell.c,该文件告诉了你如何通过命令来获取系统中的内核对象计数器,如果你的项目支持Shell的话,可以通过命令mi kernel直接的去获取内核对象,并和内存泄漏之后的值进行比较,来确定是否是Handle导致的内存泄漏,以及Handle为释放的个数。
Mi kernel命令的结果,形如:
Page size=4096, 13474 total pages, 5279 free pages. 5277 MinFree pages (33566720 current bytes, 33574912 MaxUsed bytes) 111 pages used by kernel, 0 pages held by kernel, 8195 pages consumed. Inx Size Used Max Extra Entries Name 0: 576 70848 72000 1152 123(125) Thrd 1: 64 9920 9920 0 155(155) MapView 2: 36 69552 70020 468 1932(1945) API/CStk/Prxy/HData/KMod/Celog/Wdog 3: 156 285168 287040 1872 1828(1840) Crit/Evt/Sem/Mut/Module/PgPool/FSMap/LockPrcList 4: 288 4320 4608 288 15( 16) Process 5: 524 0 0 0 0( 0) Name 6: 1024 0 0 0 0( 0) HlprStk 7: 16 6672 6800 128 417(425) cleanEvt/StubEvt/ModList/TokList/STKLIST/LockList/Alias |