• 内存池版本3单线程可变大小对象的内存池


    #include "stdafx.h"
    #include
    <windows.h>
    #include
    <MMSystem.h>
    #include
    <iostream>
    using namespace std;

    #pragma comment(lib, "winmm.lib")

    class Foo
    {
    public:
    Foo(
    int a = 0, int b = 0):m(a), n(b) {}

    private:
    int m;
    int n;
    };

    class MemoryChunk
    {
    public:
    MemoryChunk(MemoryChunk
    * next, size_t reqSize)
    {
    m_pNext
    = next;
    size_t chunkSize
    = reqSize > DEFAULT_CHUNK_SIZE ? reqSize : DEFAULT_CHUNK_SIZE;
    m_nChunkSize
    = chunkSize;
    m_pMem
    = new char[m_nChunkSize];
    m_nBytesAlreadyAllocated
    = 0;
    }

    ~MemoryChunk() {delete m_pMem;}

    void* alloc(size_t size)
    {
    void* pAddr = (void*)((size_t)m_pMem + m_nBytesAlreadyAllocated);
    m_nBytesAlreadyAllocated
    += size;
    return pAddr;
    }

    void free(void* doomed)
    {
    //do nothing
    //
    }

    MemoryChunk
    * NextMemoryChunk() const {return m_pNext;}

    size_t SpaceAvailiable()
    const {return m_nChunkSize - m_nBytesAlreadyAllocated;}

    enum{DEFAULT_CHUNK_SIZE = 4096};

    private:
    MemoryChunk
    * m_pNext;
    void* m_pMem;
    size_t m_nChunkSize;
    size_t m_nBytesAlreadyAllocated;
    };

    class ByteMemoryPool
    {
    public:
    ByteMemoryPool(size_t initSize
    = MemoryChunk::DEFAULT_CHUNK_SIZE)
    {
    m_chunkList
    = 0; //must set to null
    ExpandStorage(initSize);
    }

    ~ByteMemoryPool()
    {
    MemoryChunk
    * pChunk = m_chunkList;
    while (pChunk)
    {
    m_chunkList
    = pChunk->NextMemoryChunk();
    delete pChunk;
    pChunk
    = m_chunkList;
    }
    }

    void* alloc(size_t reqSize)
    {
    if (reqSize > m_chunkList->SpaceAvailiable())
    {
    ExpandStorage(reqSize);
    }

    return m_chunkList->alloc(reqSize);
    }

    void free(void* doomed)
    {
    m_chunkList
    ->free(doomed);
    }

    private:
    MemoryChunk
    * m_chunkList;

    void ExpandStorage(size_t reqSize)
    {
    MemoryChunk
    * pTmp = new MemoryChunk(m_chunkList, reqSize);
    m_chunkList
    = pTmp;
    }
    };


    class Foo3
    {
    public:
    Foo3(
    int a= 0, int b = 0):m_x(a), m_y(b){}
    void* operator new (size_t size)
    {
    if (m_pPool)
    return m_pPool->alloc(size);
    }

    void operator delete(void* doomed)
    {
    if (m_pPool)
    m_pPool
    ->free(doomed);
    }

    static void NewMemoryPool()
    {
    m_pPool
    = new ByteMemoryPool();
    }

    static void DeleteMemoryPool()
    {
    delete m_pPool;
    }

    private:
    int m_x;
    int m_y;

    static ByteMemoryPool* m_pPool;
    };

    ByteMemoryPool
    * Foo3::m_pPool = 0;



    int main()
    {
    DWORD time1, time2, deltaTime;
    time1
    = timeGetTime();
    for (int i=0; i<500; ++i)
    {
    Foo
    * ptrArray[1000];
    for (int j=0; j<1000; ++j)
    {
    ptrArray[j]
    = new Foo;
    }

    for (int j=0; j<1000; ++j)
    {
    delete ptrArray[j];
    }
    }

    time2
    = timeGetTime();
    deltaTime
    = time2- time1;
    cout
    <<deltaTime<<endl;

    Foo3::NewMemoryPool();
    time1
    = timeGetTime();
    for (int i=0; i<500; ++i)
    {
    Foo3
    * ptrArray[1000];
    for (int j=0; j<1000; ++j)
    {
    ptrArray[j]
    = new Foo3;
    }

    for (int j=0; j<1000; ++j)
    {
    delete ptrArray[j];
    }
    }

    time2
    = timeGetTime();
    Foo3::DeleteMemoryPool();
    deltaTime
    = time2- time1;
    cout
    <<deltaTime<<endl;

    return 0;
    }

      

    // 1.只有内存块列表的第一个元素是可以用于分配内存的内存块。

    // 2.在整个池的析构时会把所有内存归还给堆,而不是每次释放一个对象就将其内存归还给池或堆。

    // 因为之前规定只有第一个块可用于分配,若把这些内存加到第一个快会出现内存不连续的问题;若

    // 将这个释放的内存当做一个新块加到池的列表中那么就会出现有多个可以用于分配的内存块。

    // 解决办法:可以在池中配置两个表,新加一个释放的内存块的链表,可以有多个可用于分配内存的块,

    // 每次释放的内存都当做块加到这个链表中,当新分配内存时,优先遍历此表找是否有满足条件的块,若无、

    // 再去分配的链表中去找满足条件的块,若无再分配。

    //3.如果出现存储块用尽的情况,那么池就会调用ExpandStorage来分配一个新的内存块供使用。

  • 相关阅读:
    列表去重
    URL和URI的不同
    functional program language
    thinkphp5_笔记二
    关于《提问智慧》的笔记
    实习记录_2
    关于用户表的设计
    30秒运行超时的错误(Maximum execution time of 30 seconds exceeded)
    thinkphp5_笔记一
    Jquary 和Ajax实现简单的异步请求
  • 原文地址:https://www.cnblogs.com/kex1n/p/2140376.html
Copyright © 2020-2023  润新知