65.9K
CodeProject 正在变化。 阅读更多。
Home

性能计和内存泄漏检测器

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2001年12月6日

1分钟阅读

viewsIcon

98235

downloadIcon

1064

本文介绍了如何监控程序堆以检测内存泄漏。

引言

在 QA 团队工作时,我收到一项任务:“测量产品组件的性能,即它们工作期间的 CPU/内存使用情况,并检测可能的内存泄漏”。 检测内存泄漏并不是一个简单的过程。 首先是因为没有明确的技术来完成它。 最初的想法是在页面级别查看进程内存空间。 但这种方法不够精确(我认为),而且 Windows 并不总是立即释放分配的块。 因此,我决定在程序堆中使用所有组件(加载 DLL)之前和之后计算 PROCESS_HEAP_ENTRY_BUSY 节点。

详细说明

关于 CPU 使用情况 - 最初的想法也不是很明智 :) 我尝试使用 Windows NT Pdh 函数来测量 CPU 使用情况,但随后需要加载 pdh.lib。 因此,我使用了 NtQuerySystemInformation 技术(不幸的是,我不知道作者的名字,因为我通过第三方获得了源代码)。

现在,为了检测应用程序组件中的内存泄漏并获取系统资源信息,您可以定义一个如下的监控线程函数

#define PERFORMANCE_FILENAME "DocProcPerf.log"

typedef struct EVENTS
{
    HANDLE StartEvent;
    HANDLE StopEvent;
};

DWORD WINAPI UserThreadProc(LPVOID lpParameter)
{
    EVENTS* hWait = (EVENTS *)lpParameter;
    DWORD  dwStartTime = GetTickCount();

    CCompInfo* hInfo = new CCompInfo(PERFORMANCE_FILENAME);

    hInfo->HeapMakeSnapShot();
    hInfo->HeapStoreDumpToFile();

    SetEvent((HANDLE)hWait->StartEvent);

    hInfo->m_log->print( "DocProcTest started at %s\n", 
        hInfo->GetTimeString() );

    while (1)
    {
        if(WaitForSingleObject(
            (HANDLE)hWait->StopEvent,0) == WAIT_OBJECT_0)
            break;
        hInfo->m_log->print(
            "%s CPU[%d%%] Memory[%dKb]\n", 
            hInfo->GetTimeString(), 
            hInfo->GetCPUInfo(),
            hInfo->HeapCommitedBytes()/1024);
        Sleep(1000);
    };

    hInfo->m_log->print( "%s CPU[%d%%] Memory[%dKb]\n",
        hInfo->GetTimeString(), 
        hInfo->GetCPUInfo(),
        hInfo->HeapCommitedBytes()/1024);

    hInfo->m_log->print( "DocProcTest finished at %s\n",
        hInfo->GetTimeString() );
    hInfo->m_log->print( "Elapsed time %d sec\n",
        (GetTickCount() - dwStartTime)/1000 );
    hInfo->m_log->print( 
        "Total memory difference: %dKb\n\n",
        hInfo->HeapCompareSnapShots()/1024 );

    CloseHandle((HANDLE)hWait->StopEvent);
    CloseHandle((HANDLE)hWait->StartEvent);

    if (NULL != hWait)
        delete hWait;

    hInfo->HeapCompareDumpWithFile(FALSE); // basic report
    hInfo->HeapCompareDumpWithFile(TRUE);  // extended report

    if (NULL != hInfo)
        delete hInfo;

    return 0;
}

因此,我们只需要在 main 应用程序函数中添加我们的保持观察线程初始化行即可,如下所示

printf(  "\nTest started.\n");
EVENTS *hEvent = new EVENTS;
hEvent->StartEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
hEvent->StopEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

HANDLE hTread = CreateThread( NULL,
                             NULL,
                             UserThreadProc,
                             hEvent,
                             NULL,
                             NULL); 
WaitForSingleObject((HANDLE)hEvent->StartEvent,15000);

...
//program body goes here
...

if (NULL != hEvent)
SetEvent((HANDLE)hEvent->StopEvent);
while (WaitForSingleObject(hTread,1000) != WAIT_OBJECT_0)
Sleep(1000);
printf(  "\nTest finished.\n");

总而言之,我想补充一点,这种方法目前正在研究中,因此欢迎随时向我咨询新的内容或对其进行修改。 我将感谢您的评论和建议。

性能仪表和内存泄漏检测器 - CodeProject - 代码之家
© . All rights reserved.