zoukankan      html  css  js  c++  java
  • 统计windows crt库内存使用情况

    1. 关于heap类型

    From http://msdn.microsoft.com/en-us/library/wc28wkas%28v=vs.80%29.aspx
    有如下几种heap block: _NORMAL_BLOCK, _CLIENT_BLOCK, _FREE_BLOCK,
    关于不同heap block区别 http://msdn.microsoft.com/en-us/library/htdyz80k%28v=vs.80%29.aspx

       A normal block is ordinary memory allocated by your program.
    
        A client block is a special type of memory block used by MFC programs for objects that require a destructor. The MFC new operation creates either a normal block or a client block, as appropriate for the object being created.
    
        A CRT block is a block of memory allocated by the CRT library for its own use. The CRT library handles the deallocation for these blocks, so it is unlikely you will see these in the memory leak report unless something is seriously wrong (for example, the CRT library is corrupted).
    
        A free block is a block of memory that has been released.
    
        An ignore block is a block that you have specifically marked so it doesn't appear in the memory leak report.
    View Code

    2. 打印当前crt heap使用情况的一段代码

    inline unsigned long asm_getmemallocsize(void)
    {
                _CrtMemState stMemState;
     
                memset( &stMemState, 0, sizeof(stMemState));
                // Get the allocated size
                _CrtMemCheckpoint( &stMemState );
                return stMemState.lSizes[1];      // 1 means Normal Blocks
    }
    View Code

    3. 关于_CrtMemState中一个属性lTotalCount有bug
    http://www.flounder.com/bugincrtmemcheckpoint.htm

    4. 使用_heapwalk打印当前heap使用大小(俺比较奇怪跟2有啥不同?)

    /****************************************************************************
    *                                  CountWalk
    * Result: UINT
    *       Amount of space allocated as revealed by _heapwalk
    ****************************************************************************/
    
    UINT CountWalk()
        {
         int HeapStatus;
         BOOL running = TRUE;
         _HEAPINFO info;
         info._pentry = NULL;
         UINT UsedBytes = 0;
         
         while(running)
            { /* scan heap */
             HeapStatus = _heapwalk(&info);
             switch(HeapStatus)
                { /* check status */
                 case _HEAPOK:
                    break;
                 case _HEAPEND:
                    running = FALSE;
                    break;
                 default:
                    ASSERT(FALSE);
                    running = FALSE;
                    continue;
                } /* check status */
    
             if(info._useflag == _USEDENTRY)
                { /* used block */
                 UsedBytes += info._size;
                } /* used block */
            } /* scan heap */
         return UsedBytes;
        } // CountWalk
    View Code

     5. 从windows系统角度,有如下几种heap类型: standard, look-aside, low-fragmentation (LFH)
    msdn提供了一些函数来获取heap信息,包括有几个heap,每个heap是什么类型

    // From http://msdn.microsoft.com/en-us/library/windows/desktop/ee175820%28v=vs.85%29.aspx
    
    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    #include <intsafe.h>
    
    int HeapInfo(HANDLE hHeap);
    
    int __cdecl _tmain()
    {
        DWORD NumberOfHeaps;
        DWORD HeapsIndex;
        DWORD HeapsLength;
        HANDLE hDefaultProcessHeap;
        HRESULT Result;
        PHANDLE aHeaps;
        SIZE_T BytesToAllocate;
    
        //
        // Retrieve the number of active heaps for the current process
        // so we can calculate the buffer size needed for the heap handles.
        //
        NumberOfHeaps = GetProcessHeaps(0, NULL);
        if (NumberOfHeaps == 0) {
            _tprintf(TEXT("Failed to retrieve the number of heaps with LastError %d.\n"),
                     GetLastError());
            return 1;
        }
    
        //
        // Calculate the buffer size.
        //
        Result = SIZETMult(NumberOfHeaps, sizeof(*aHeaps), &BytesToAllocate);
        if (Result != S_OK) {
            _tprintf(TEXT("SIZETMult failed with HR %d.\n"), Result);
            return 1;
        }
    
        //
        // Get a handle to the default process heap.
        //
        hDefaultProcessHeap = GetProcessHeap();
        if (hDefaultProcessHeap == NULL) {
            _tprintf(TEXT("Failed to retrieve the default process heap with LastError %d.\n"),
                     GetLastError());
            return 1;
        }
    
        //
        // Allocate the buffer from the default process heap.
        //
        aHeaps = (PHANDLE)HeapAlloc(hDefaultProcessHeap, 0, BytesToAllocate);
        if (aHeaps == NULL) {
            _tprintf(TEXT("HeapAlloc failed to allocate %d bytes.\n"),
                     BytesToAllocate);
            return 1;
        }
    
        // 
        // Save the original number of heaps because we are going to compare it
        // to the return value of the next GetProcessHeaps call.
        //
        HeapsLength = NumberOfHeaps;
    
        //
        // Retrieve handles to the process heaps and print them to stdout. 
        // Note that heap functions should be called only on the default heap of the process
        // or on private heaps that your component creates by calling HeapCreate.
        //
        NumberOfHeaps = GetProcessHeaps(HeapsLength, aHeaps);
        if (NumberOfHeaps == 0) {
            _tprintf(TEXT("Failed to retrieve heaps with LastError %d.\n"),
                     GetLastError());
            return 1;
        }
        else if (NumberOfHeaps > HeapsLength) {
    
            //
            // Compare the latest number of heaps with the original number of heaps.
            // If the latest number is larger than the original number, another
            // component has created a new heap and the buffer is too small.
            //
            _tprintf(TEXT("Another component created a heap between calls. ") \
                     TEXT("Please try again.\n"));
            return 1;
        }
    
        _tprintf(TEXT("Process has %d heaps.\n"), HeapsLength);
        for (HeapsIndex = 0; HeapsIndex < HeapsLength; ++HeapsIndex) {
            _tprintf(TEXT("Heap %d at address: %#p.\n"),
                     HeapsIndex,
                     aHeaps[HeapsIndex]);
    
            HeapInfo(aHeaps[HeapsIndex]);
        }
      
        //
        // Release memory allocated from default process heap.
        //
        if (HeapFree(hDefaultProcessHeap, 0, aHeaps) == FALSE) {
            _tprintf(TEXT("Failed to free allocation from default process heap.\n"));
        }
    
        return 0;
    }
    
    
    //  From http://msdn.microsoft.com/en-us/library/windows/desktop/aa366703%28v=vs.85%29.aspx
    //#include <windows.h>
    //#include <tchar.h>
    //#include <stdio.h>
    
    #define HEAP_STANDARD 0
    #define HEAP_LAL 1
    #define HEAP_LFH 2
    
    int HeapInfo(HANDLE hHeap)
    {
         ULONG HeapInformation;
    
         _tprintf(TEXT("heap at address: %#p.\n"), hHeap);
    
        //
        // Query heap features that are enabled.
        //
        BOOL bResult = HeapQueryInformation(hHeap,
                                       HeapCompatibilityInformation,
                                       &HeapInformation,
                                       sizeof(HeapInformation),
                                       NULL);
        if (bResult == FALSE) {
            _tprintf(TEXT("Failed to retrieve heap features with LastError %d.\n"),
                     GetLastError());
            return 1;
        }
    
        //
        // Print results of the query.
        //
        _tprintf(TEXT("HeapCompatibilityInformation is %d.\n"), HeapInformation);
        switch(HeapInformation)
        {
        case HEAP_STANDARD:
            _tprintf(TEXT("The default process heap is a standard heap.\n"));
            break;
        case HEAP_LAL:
            _tprintf(TEXT("The default process heap supports look-aside lists.\n"));
            break;
        case HEAP_LFH:
            _tprintf(TEXT("The default process heap has the low-fragmentation ") \
                     TEXT("heap enabled.\n"));
            break;
        default:
            _tprintf(TEXT("Unrecognized HeapInformation reported for the default ") \
                     TEXT("process heap.\n"));
            break;
         }
    
        return 0;
    }
    View Code
  • 相关阅读:
    链表查找问题总结
    部分有序中查找给定值-【百度面试题】循环有序数组的查找问题
    为何要将整型变量强制转化为指针
    洗牌算法汇总
    如果有三个Bool型变量,请写出一程序得知其中有2个以上变量的值是true
    利用宏来求结构体成员偏移值
    水塘抽样问题
    Javascript 装载和执行
    git ssh认证
    git 配置文件
  • 原文地址:https://www.cnblogs.com/cutepig/p/3132369.html
Copyright © 2011-2022 走看看