C++ 封装私有堆(Private Heap) 创建进程私有堆
Heap,创建进程私有堆
http://blog.csdn.net/hisinwang/article/details/45115885
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
    // Create a private heap
    HANDLE hHeapNew = HeapCreate(0,         // serialized and no exception
                                 1024*4,    // the initial size of the heap
                                 1024*16);  // the maximum size of the heap
    if (hHeapNew == NULL)
    {
        cout << "HeapCreate failed with error: " << GetLastError() << endl;
        return 0;
    }
    // Allocate a block of memory from the private heap
    LPVOID lpBuffer = HeapAlloc(hHeapNew,           // heap handle
                                HEAP_ZERO_MEMORY,   // initialized to be 0
                                100);               // number of bytes to be allocated
    if (lpBuffer == NULL)
    {
        cout << "HeapAlloc failed with error: " << GetLastError() << endl;
        return 0;
    }
    sprintf((char*)lpBuffer, "Hello Kitty");
    cout << (char*)lpBuffer << endl;
    // Free the memory block allocated from the private heap
    BOOL flag;
    flag = HeapFree(hHeapNew, 0, lpBuffer);
    if (!flag)
    {
        cout << "HeapFree failed with error: " << GetLastError() << endl;
        return 0;
    }
    // Destroy the heap 
    flag = HeapDestroy(hHeapNew);
    if (!flag)
    {
        cout << "HeapDestroy failed with error: " << GetLastError() << endl;
        return 0;
    }
    system("pause");
    return 0;
}
- 1
 - 2
 - 3
 - 4
 - 5
 - 6
 - 7
 - 8
 - 9
 - 10
 - 11
 - 12
 - 13
 - 14
 - 15
 - 16
 - 17
 - 18
 - 19
 - 20
 - 21
 - 22
 - 23
 - 24
 - 25
 - 26
 - 27
 - 28
 - 29
 - 30
 - 31
 - 32
 - 33
 - 34
 - 35
 - 36
 - 37
 - 38
 - 39
 - 40
 - 41
 - 42
 - 43
 - 44
 - 45
 - 46
 - 47
 - 48
 - 49
 - 50
 

                
            
浙公网安备 33010602011771号
C++ 封装私有堆(Private Heap)
Private Heap 是 Windows 提供的一种内存内存机制,对于那些需要频繁分配和释放动态内存的应用程序来说,Private Heap 是提高应用程序性能的一大法宝,使用它能降低 new / malloc 的调用排队竞争以及内存空洞。Private Heap 的原理及应用的资料很多,这里就不一一介绍了,常用的 Private Heap API 有以下几个,具体介绍请参考帮助文档:
由于是 C 风格的 API,使用起来比较繁琐,因此本座在闲暇之余用 C++ 对这些 API 进行了封装,主要包括两个类:
#pragma once class CPrivateHeap { public: enum EnCreateOptions { CO_DEFAULT = 0, CO_NO_SERIALIZE = HEAP_NO_SERIALIZE, CO_GENERATE_EXCEPTIONS = HEAP_GENERATE_EXCEPTIONS, CO_NOSERIALIZE_GENERATEEXCEPTIONS = HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS }; enum EnAllocOptions { AO_DEFAULT = 0, AO_ZERO_MEMORY = HEAP_ZERO_MEMORY, AO_NO_SERIALIZE = HEAP_NO_SERIALIZE, AO_GENERATE_EXCEPTIONS = HEAP_GENERATE_EXCEPTIONS, AO_ZEROMEMORY_NOSERIALIZE = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, AO_ZEROMEMORY_GENERATEEXCEPTIONS = HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, AO_NOSERIALIZE_GENERATESEXCEPTIONS = HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS, AO_ZEROMEMORY_NOSERIALIZE_GENERATESEXCEPTIONS = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS }; enum EnReAllocOptions { RAO_DEFAULT = 0, RAO_ZERO_MEMORY = HEAP_ZERO_MEMORY, RAO_NO_SERIALIZE = HEAP_NO_SERIALIZE, RAO_GENERATE_EXCEPTIONS = HEAP_GENERATE_EXCEPTIONS, RAO_REALLOC_IN_PLACE_ONLY = HEAP_REALLOC_IN_PLACE_ONLY, RAO_ZEROMEMORY_NOSERIALIZE = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, RAO_ZEROMEMORY_GENERATEEXCEPTIONS = HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, RAO_ZEROMEMORY_REALLOCINPLACEONLY = HEAP_ZERO_MEMORY | HEAP_REALLOC_IN_PLACE_ONLY, RAO_NOSERIALIZE_GENERATESEXCEPTIONS = HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS, RAO_NOSERIALIZE_REALLOCINPLACEONLY = HEAP_NO_SERIALIZE | HEAP_REALLOC_IN_PLACE_ONLY, RAO_GENERATESEXCEPTIONS_REALLOCINPLACEONLY = HEAP_GENERATE_EXCEPTIONS | HEAP_REALLOC_IN_PLACE_ONLY, RAO_ZEROMEMORY_NOSERIALIZE_GENERATESEXCEPTIONS = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS, RAO_ZEROMEMORY_NOSERIALIZE_REALLOCINPLACEONLY = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE | HEAP_REALLOC_IN_PLACE_ONLY, RAO_ZEROMEMORY_GENERATESEXCEPTIONS_REALLOCINPLACEONLY = HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS | HEAP_REALLOC_IN_PLACE_ONLY, RAO_NOSERIALIZE_GENERATESEXCEPTIONS_REALLOCINPLACEONLY = HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS | HEAP_REALLOC_IN_PLACE_ONLY, RAO_ZEROMEMORY_NOSERIALIZE_GENERATESEXCEPTIONS_REALLOCINPLACEONLY = HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE | HEAP_GENERATE_EXCEPTIONS | HEAP_REALLOC_IN_PLACE_ONLY }; enum EnSizeOptions { SO_DEFAULT = 0, SO_NO_SERIALIZE = HEAP_NO_SERIALIZE }; enum EnFreeOptions { FO_DEFAULT = 0, FO_NO_SERIALIZE = HEAP_NO_SERIALIZE }; enum EnCompactOptions { CPO_DEFAULT = 0, CPO_NO_SERIALIZE = HEAP_NO_SERIALIZE }; public: PVOID Alloc(DWORD size, EnAllocOptions options = AO_DEFAULT) {return ::HeapAlloc(m_heap, options, size);} PVOID ReAlloc(PVOID pvmem, DWORD size, EnReAllocOptions options = RAO_DEFAULT) {return ::HeapReAlloc(m_heap, options, pvmem, size);} DWORD Size(PVOID pvmem, EnSizeOptions options = SO_DEFAULT) {return (DWORD)::HeapSize(m_heap, options, pvmem);} BOOL Free(PVOID pvmem, EnFreeOptions options = FO_DEFAULT) {return ::HeapFree(m_heap, options, pvmem);} DWORD Comapct(EnCompactOptions options = CPO_DEFAULT) {return (DWORD)::HeapCompact(m_heap, options);} BOOL IsValid() {return m_heap != NULL;} public: CPrivateHeap(EnCreateOptions options = CO_DEFAULT, DWORD initsize = 0, DWORD maxsize = 0) {m_heap = ::HeapCreate(options, initsize, maxsize);} ~CPrivateHeap() {if(IsValid()) ::HeapDestroy(m_heap);} private: CPrivateHeap(const CPrivateHeap&); CPrivateHeap operator = (const CPrivateHeap&); private: HANDLE m_heap; }; template<class T> class CPrivateHeapBuffer { public: CPrivateHeapBuffer( CPrivateHeap& heap, DWORD size = 0, CPrivateHeap::EnAllocOptions allocoptions = CPrivateHeap::AO_DEFAULT, CPrivateHeap::EnFreeOptions freeoptions = CPrivateHeap::FO_DEFAULT) : m_hpPrivate(heap) , m_opFree(freeoptions) { ASSERT(m_hpPrivate.IsValid()); m_pvMemory = (T*)m_hpPrivate.Alloc(size * sizeof(T), allocoptions); } ~CPrivateHeapBuffer() {m_hpPrivate.Free(m_pvMemory, m_opFree);} T* ReAlloc(DWORD size, CPrivateHeap::EnReAllocOptions options = CPrivateHeap::RAO_DEFAULT) {return m_pvMemory = (T*)m_hpPrivate.ReAlloc(m_pvMemory, size * sizeof(T), options);} DWORD Size(CPrivateHeap::EnSizeOptions options = CPrivateHeap::SO_DEFAULT) {return m_hpPrivate.Size(m_pvMemory, options);} operator T* () const {return m_pvMemory;} private: CPrivateHeapBuffer(const CPrivateHeapBuffer&); CPrivateHeapBuffer operator = (const CPrivateHeapBuffer&); private: CPrivateHeap& m_hpPrivate; T* m_pvMemory; CPrivateHeap::EnFreeOptions m_opFree; }; typedef CPrivateHeapBuffer<BYTE> CPrivateHeapByteBuffer; typedef CPrivateHeapBuffer<TCHAR> CPrivateHeapStrBuffer;上述代码看起来挺复杂,但使用起来却是异常简单的,请看下面的使用示例:
// 全局可见的 Heap CPrivateHeap g_heap; class MyClass { private: // 与类实例生命周期一致的 Heap CPrivateHeap m_heap; // 仅类内部可见的 Heap static CPrivateHeap sm_heap; public: void test_m_eap() { // 无需显式释放堆内存 CPrivateHeapStrBuffer buff(m_heap, 32); lstrcpy(buff, _T("失败乃成功之母")); DWORD size = buff.Size(); buff.ReAlloc(40 * sizeof(TCHAR)); size = buff.Size(); std::cout << (TCHAR*)buff << '\n'; } static void test_sm_eap() { CPrivateHeapStrBuffer buff(sm_heap, 32); lstrcpy(buff, _T("失败乃成功之母")); DWORD size = buff.Size(); buff.ReAlloc(40 * sizeof(TCHAR)); size = buff.Size(); std::cout << (TCHAR*)buff << '\n'; } }; void test_g_heap() { // 如果不使用 CPrivateHeapBuffer<T> 来封装堆内存 ASSERT(g_heap.IsValid()); TCHAR* pch = (TCHAR*)g_heap.Alloc(32 * sizeof(TCHAR)); lstrcpy(pch, _T("失败乃成功之母")); DWORD size = g_heap.Size(pch); g_heap.ReAlloc(pch, 40 * sizeof(TCHAR)); size = g_heap.Size(pch); std::cout << pch << '\n'; // 需要显式释放堆内存 g_heap.Free(pch); } int _tmain(int argc, _TCHAR* argv[]) { test_g_heap(); MyClass::test_sm_eap(); MyClass c; c.test_m_eap(); return 0; }