加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Memory Pool Implementation

发布时间:2020-12-15 07:27:16 所属栏目:Java 来源:网络整理
导读:The memory pool is designed to improve performance especially in real time system. It‘s designed to reduce the performance penalty caused by frequent use of system calls such as malloc/free in C or new/delete in C++. Frequent use of memor


The memory pool is designed to improve performance especially in real time system. It‘s designed to reduce the performance penalty caused by frequent use of system calls such as malloc/free in C or new/delete in C++. Frequent use of memory-managed system calls can cause performance bottlenecks when our programs need to apply and release memory frequently.

?

使用内存池的目的:

  1. 减少频繁使用 malloc/free或new/delete 等系统调用而造成的性能损耗。当我们的程序需要频繁地申请和释放内存时,频繁地使用内存管理的系统调用可能会造成性能的瓶颈
  2. 减少系统内存碎片的产生
  3. 降低内存泄漏的风险

??

设计:

  1. 用一个vector保存所有的内存。
  2. 用一个hash table(unordered_map)来标记哪个block在可用列表里。

?

为什么不用unordered_set?

unordered_set牵扯到动态分配更多内存?

http://www.cplusplus.com/reference/unordered_set/unordered_set/insert/

The storage for the new element is allocated using allocator_traits<allocator_type>::construct(),which may throw exceptions on failure (for the default allocator,bad_alloc is thrown if the allocation request does not succeed).

反而我们用unordered_map中的value来判断一个block是否是free的。

?

为什么不用linked list维护当前可用的block?

linked list在添加和删除node的时候牵扯到内存的分配/释放,违背了memory pool设计的初衷。

?

?

C++代码(未调试)

#include <iostream> 
#include <unordered_map>
#include <vector>

using namespace std;

#define NO_ERROR                    0
#define ERR_ZERO_BLOCK_SIZE            1
#define ERR_OUT_OF_MEMORY            2
#define ERR_NULL_POINTER            3
#define ERR_EMPTY_POOL                4
#define ERR_MEMORY_ALREADY_FREED    5
#define ERR_INVALID_BLOCK_ADDRESS    6

typedef enum block_flag {
    FREE,IN_USE
} block_flag_t;

class Memory_Pool {
public:
    int allocate_memory_pool(const size_t block_size,const unsigned int block_count) {
        int err_code = NO_ERROR;

        if (block_size == 0)
            err_code = ERR_ZERO_BLOCK_SIZE;

        if (err_code == NO_ERROR) {
            free_count = 0;
            void* new_block = malloc(block_size * block_count);
            if (new_block == NULL) {
                err_code = ERR_OUT_OF_MEMORY;
            }
            else {
                for (int i = 0; i < block_count; i++) {
                    pool.push_back((char*)new_block + i*block_size);
                    block_status[new_block] = FREE;
                    free_count++;
                }
            }
        }
        
        if (err_code != NO_ERROR)
            free_memory_pool();

        return err_code;
    }

    void free_memory_pool() {
        for (char* block : pool)
            if (block) free(block);
    }

    int retrieve_block(char** block) {
        int err_code = NO_ERROR;

        if (block == NULL)
            err_code = ERR_NULL_POINTER;

        if ((err_code == NO_ERROR) && (free_count == 0))
            err_code = ERR_EMPTY_POOL;

        if (err_code == NO_ERROR) {
            block_status[block] == IN_USE;
            free_count--;
            *block = pool[free_count];
        }

        return err_code;
    }

    int return_block(char* block) {
        int err_code = NO_ERROR;

        if (block == NULL)
            err_code = ERR_NULL_POINTER;

        if ((err_code == NO_ERROR) && (block_status[block] == FREE))
            err_code = ERR_MEMORY_ALREADY_FREED;

        if ((err_code == NO_ERROR) && (block_status.find(block) == block_status.end()))
            err_code = ERR_INVALID_BLOCK_ADDRESS;

        if (err_code == NO_ERROR) {
            pool[free_count] = block;
            free_count++;
            block_status[block] = FREE;
        }

        return err_code;
    }

private:
    vector <char*> pool;
    int free_count;
    unordered_map <void*,block_flag_t> block_status;
};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读