简言

1. boost的对象池object_pool在释放时采用的遍历,有性能问题

2. 也不是什么大问题,优化后可用。但是仅仅为了一个对象池,引入boost,没必要

3. 笔者这里一份简单实现的对象池,windows和linux下通用

4. 代码量很小,仅仅两百行,支持对象池高峰过后,逐步回收

接口介绍

1. // 初始化(初始数量,一次增长的数量, 单次收缩的数量)

bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50);

2. // 分配一个新对象
    T* alloc();

3. // 回收一个对象
    void dealloc(T* pObj);

4. // 执行一次回收,用来使用高峰过后的缩减
    void dorecycle();

代码下载地址

windows版:https://download.csdn.net/download/yzf279533105/11989303

实验如下图(特意标记出来两次回收之后的,每次回收50个,空闲列表free_list的数量)

完整代码

#pragma once#include <unordered_set>
#include <string.h>//对象池模板类
template<class T>
class class_obj_pool
{
public:enum{MAX_INIT_NUM = 100000, // 初始化最大数量,暂定10万};class_obj_pool(){clear();}~class_obj_pool(){clear();}
public:// 初始化(初始数量,一次增长的数量, 单次收缩的数量)bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50){// 参数检测if (initNum <= 0 || increaseNum <= 0 || reduceNum <= 0){printf("init(), param error, initNum=%d, nIncreaseNum=%d, reduceNum=%d\n", initNum, increaseNum, reduceNum);return false;}nInitNum     = initNum;nIncreaseNum = increaseNum;nShrinkNum       = reduceNum;// 参数修正nInitNum        = nInitNum>MAX_INIT_NUM ? MAX_INIT_NUM : nInitNum;          // 初始个数nIncreaseNum = nIncreaseNum>MAX_INIT_NUM ? MAX_INIT_NUM : nIncreaseNum;  // 一次增长的数量// 初始化对象for (int i = 0; i<nInitNum; ++i){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("new obj failed \n");continue;}// T对象需提供init函数进行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}free_list.insert(pObj);}return true;}// 分配一个新对象T* alloc(){T* pRet = NULL;// 空闲列表中有,则取一个if (free_list.size() > 0){unordered_set<T*>::iterator iter = free_list.begin();pRet = *iter;free_list.erase(iter);used_list.insert(pRet);// 超过最大使用记录量,则更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 空闲列表中没有时,则新建一批for (int i = 0; i<nIncreaseNum; i++){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("alloc(), new obj failed \n");continue;}// T对象需提供init函数进行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}// 没赋值的先赋值;已赋值的压入空闲列表if (pRet == NULL){pRet = pObj;used_list.insert(pObj);}else{free_list.insert(pObj);}}// 超过最大使用记录量,则更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 回收一个对象void dealloc(T* pObj){if (pObj == NULL){printf("dealloc(), pObj == NULL");return;}// 不存在unordered_set<T*>::iterator it = used_list.find(pObj);if (it == used_list.end()){printf("dealloc(), find pObj failed \n");return;}// T对象需提供reset()函数进行重置pObj->reset();free_list.insert(pObj);used_list.erase(pObj);}// 执行一次回收,用来使用高峰过后的缩减void dorecycle(){// 空闲列表中有对象,且超过一次增量时,才进行回收int nfree = free_list.size();if (nfree <= nIncreaseNum){return;}// 要回收的数量nfree = (nfree - nIncreaseNum);int i = 0;for (unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end();){T* pObj = *iter;if (pObj != NULL){delete pObj;}free_list.erase(iter++);// 超过一次回收的最大量,就跳出i++;if (i>=nShrinkNum){break;}}}// 打印出各个变量void showinfo(){printf("free_list.size=%d, used_list.size=%d, nUsedMax=%d \n", free_list.size(), used_list.size(), nUsedMax);}// 回收void clear(){for (std::unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}free_list.clear();for (std::unordered_set<T*>::iterator iter = used_list.begin(); iter != used_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}used_list.clear();nInitNum = 0; // 初始个数nUsedMax = 0;   // 曾经使用的最大个数nIncreaseNum = 0;  // 一次增长的数量nShrinkNum = 0;  // 单次回收的最大数量}
private:std::unordered_set<T*>    free_list;      // 空闲列表std::unordered_set<T*>     used_list;      // 使用中的列表int                    nInitNum;       // 初始个数int                  nUsedMax;       // 曾经使用的最大个数int                     nIncreaseNum;   // 一次增长的数量int                   nShrinkNum;     // 单次回收的最大数量
};

c++实现,对象池 object_pool相关推荐

  1. python求5_python(五)——运算符,小整数对象池

    1.成员运算符,判断某个东西是否在某个东西里包含:in,not in name = "abcd" if "ac" inname:print("ok&q ...

  2. 面试官问:对象池技术了解吗?apache common pool2呢?

    欢迎关注方志朋的博客,回复"666"获面试宝典 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是 ...

  3. golang的临时对象池sync.Pool

    今天在写码之时,发现了同事用到了sync.pool.因不知其因,遂Google之.虽然大概知道其原因和用法.还不能融汇贯通.故写此记,方便日后查阅.直至明了. 正文 在高并发或者大量的数据请求的场景中 ...

  4. 转载 Xmlhttprequest对象池

    2019独角兽企业重金招聘Python工程师标准>>> 在ajax应用中,通常一个页面要同时发送多个请 求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就 ...

  5. [转]建一个XMLHttpRequest对象池

    在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的XMLHttpRequest对象,也 ...

  6. Unity中对象池的使用

    unity中用到大量重复的物体,例如发射的子弹,可以引入对象池来管理,优化内存. 对象池使用的基本思路是: 将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用.恰当地使用对象池,可以在 ...

  7. Java 程序优化之对象池

    对象池概念: 如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类都一些实例保存到一个"池"中,待需要使用的时候直接从"池"中获取.这个" ...

  8. python整数池_【Python】Python中神奇的小整数对象池和大整数对象池

    小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立 ...

  9. cocos对象池的使用

    enemy.js cc.Class({extends: cc.Component,properties: {enemySpeed: 0, //设置加速度 },//初始化当前节点的y坐标init: fu ...

最新文章

  1. 了解 ElasticSearch 这几个知识点后,查询起飞~
  2. python的四种内置数字类型_浅析Python数字类型和字符串类型的内置方法
  3. 找不到 tools.jar。请检查 C:\Program Files\Java\jre1.8.0_151 是否包含有效的 JDK 安装
  4. 【python】python redis的安装与使用
  5. 汉字笔画数据_把所有汉字叠起来会怎样?
  6. 前端学习(2820):全局文件tabber字段
  7. TF下载量已超4600万!首届TensorFlow World大会,谷歌大牛Jeff Dean激情演讲
  8. RMAN备份与恢复(三)--备份相关概念
  9. 在3.5下实现无配置WCF服务
  10. Indent Guides插件格式代码
  11. 精通git中文版 (连载四)
  12. 【全网最简单】给朋友- 制作,微信公众号推送教程
  13. 京东智能客服言犀启发式问答技术探秘
  14. 【爬虫】抓取msdn.itellyou.cn所有操作系统镜像下载链接
  15. Mac如何查看系统根目录
  16. Java多用户商城源码/单商户商城系统源码
  17. 计算n个整数中有多少个正整数、多少个负整数,并计算这些整数的总和和平均值
  18. C++PrimerPlus
  19. Android在CMD中输入adb命令,提示“'adb' 不是内部或外部命令,也不是可运行的程序”的解决方法
  20. 2019最新《传智教育黑马java项目实战》

热门文章

  1. Cisco SSL ×××
  2. .Net 事件类型的实现和推荐做法
  3. CodeForces - 985F Isomorphic Strings(字符串哈希)
  4. (转)快速统计二进制中1的个数
  5. CH - 0104 起床困难综合症(位运算+贪心)
  6. 广度优先遍历算法-03树的右侧问题
  7. mysql avg 报错_MySQL报错汇总
  8. 《qss样式表笔记大全(二):可设置样式的窗口部件列表(上)(包含相关示例)》
  9. live555 源码分析:ServerMediaSession
  10. C++ 面向对象(三)异常 :异常概念、异常的匹配规则、异常安全、异常体系