我已经设置了一个测试工具来测试我正在为项目开发的DLL中的一组函数。
我想验证这些函数在Windows系统上没有内存泄漏。
我已正确设置UMDH,并且我能够在两个堆转储之间获得比较文件。即使堆栈迹线也很好。
差异的输出困扰着我,我希望有人可以帮助解释我为什么得到我得到的输出。
+ 56 ( 56 - 0) 1 allocs BackTrace9C160
+ 1 ( 1 - 0) BackTrace9C160 allocations
我将log1和log2设置为1个整数分配,只是为了验证我的设置。
实际上,它只显示了1个分配,但是,它表示从之前和之后有56个字节的变化。我只希望sizeof(int)以字节为单位进行更改。在我的系统上,int分配的size是4个字节,所以我期望看到+4,而不是+56。
同样,在日志之间运行的唯一代码行是
new int; //purposely leak memory
有任何解释吗?
IDE /编译器:Visual Studio 2010
应用程序是64位
涉及到DLL(但我在这个简单的int分配示例中甚至没有调用它)
如果我注释掉泄漏,我得到零分配和+0字节。所以我认为这可以验证应用程序中的任何其他地方都没有额外的字节,只需从上面显示的那一行开始......
请参阅下面的SleuthEye解决方案。此外,我在评论中添加了一条评论,我认为该评论对最终使用此问题的人有益:
此外,如果您在.exe的发布版本上运行此程序并在运行目录中包含程序调试数据库,umdh将提取源文件名和内存泄漏的行号,同时保持准确的字节计数。就内存泄漏搜索而言,这为您提供了调试和发布版本的好处。
答案 0 :(得分:4)
56个字节来自C运行时库(CRT)在使用调试堆时分配的额外内存,如MSDN所述。
查看dbbint.h,其中_CrtMemBlockHeader
结构定义为:
#define nNoMansLandSize 4
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
#ifdef _WIN64
/* These items are reversed on Win64 to eliminate gaps in the struct
* and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is
* maintained in the debug heap.
*/
int nBlockUse;
size_t nDataSize;
#else /* _WIN64 */
size_t nDataSize;
int nBlockUse;
#endif /* _WIN64 */
long lRequest;
unsigned char gap[nNoMansLandSize];
/* followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
} _CrtMemBlockHeader;
之后会为您的int
分配内存,然后再增加4个字节" NoMansLand"缓冲。因此,对于64位应用程序,单个int
的测试用例的总分配内存最多为sizeof(_CrtMemBlockHeader)+sizeof(int)+4
= 48+4+4
= 56
。
请注意,在发布版本上运行相同的分析(其中未分配_CrtMemBlockHeader
)会生成以下比较日志输出:
+ 4 ( 4 - 0) 1 allocs BackTrace2
+ 1 ( 1 - 0) BackTrace2 allocations
答案 1 :(得分:3)
您可以使用UMDH Diff Viz工具轻松阅读比较输出。