这里写目录标题

  • 思考
  • 什么是内存池?
    • 内存池作用
    • 内存池的演变
      • 版本一
      • 版本二
  • 总结
  • 后续

思考

  1. 什么是内存池?内存池是做什么的?核心是什么?(心想这不是废话吗!肯定时管理内存的,具体呢)。
  2. 内存池这个所谓的“池子”怎么建造比较好?
  3. 内存池的使用场景?
  4. 有什么好的“轮子”使用?要不要自己“造轮子”?什么时候真的适合自己“造轮子”?如果造轮子,怎么造一个好用“轮子”?

充电站
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

什么是内存池?

形象解释:它的名字起的还是很贴切的,就像一个人叫“胖虎”,那他肯定是比较胖的,哈哈。起一个不太恰当的例子,一个所谓的“渣男”、“渣女”有一个“池塘”,更有甚者是“海洋”。有了这样的池塘以后就很方便,需要了就直接取用。比如“渣女”今天想吃水果了,心情不好需要安慰。在“池塘”里捞一个“老实人”就很方便的达到目的。如果没有这样的池塘,自己又不想动,取寻找培养一个“老实人”是很花费时间的,达到目的后就冷落了,如果彻底断绝联系吧,万一以后还有有用的地方对吧?所以干脆放在自己的“鱼塘”。(这里只是举个例子,希望不要被喷啊)。
学术点解释是在计算技术中经常使用的一种设计模式,其内涵在于:将程序中需要经常使用的核心资源先申请出来,放到一个池内,有程序自管理,这样可以提高资源的利用率,也可以保证本程序占有的资源数量。内存池(Memory Pool)是一种动态内存分配与管理技术,内存池则是在真正使用内存之前,先申请分配一大块内存(内存池)留作备用。当程序员申请内存时,从池中取出一块动态分配,当程序员释放时,将释放的内存放回到池内,再次申请,就可以从池里取出来使用,并尽量与周边的空闲内存块合并。

内存池作用

  内存池对一个空白的内存进行维护的过程,主要是对进行管理的。其核心是避免频繁的内存分配与释放。
  Linux下进程开始运行的时候,内存就 被划分出来了,这里面主要包括内核空间用户空间。用户空间主要能管理的就是mmap与堆,mmap有些进程没有,所以主要的还是对堆的管理。

客户端与服务器连接的中,当客户端send()数据给服务器,服务器在recv()之前需要有一块内存进行数据的存储。肯定会想到定义一个char buffer[],但时定义的buffer在栈区,随着函数的返回会被释放掉。这就需要在recv()之前malloc()出一个内存空间,给recv()去使用。这个过程可能还伴随着数据库的连接,recv()完以后进行业务处理。malloc()出来的内存存储的数据生命周期在整个连接过程中。
  在多个客户端进进行服务器连接的过程,必然会带来内存频繁的连接与释放。这样在申请和释放的过程造成利用率很低的一个主要原因就是内存碎片化。如果有未使用的存储器,但是这块存储器不能用来满足分配的请求,这时候就会产生内存碎片化问题。

综上所述:解决内存频繁分内,造成内存碎片化的方法就是内存池,再提一点,再工作当中,尽量是要用,不要自己造,但原理一定要明白

内存池的演变

版本一

最早的内存池雏形,malloc()申请一次内存,就用链表组织起来。将用到的内存加入uselist中,并且重载free()函数,设置flag。当释放内存是,用flag标记该内存未使用。当下次再需要内存是就在链表中找,再进行利用。

伪代码

// 伪代码
//节点结构体
struct memnode {void *addr;int size;int flag; //1 use, 0 freestruct memonde *next;
}//定义内存池
struct memnode *mempool;//重载malloc()
void *nmalloc() {void *addr = malloc();struct memnode *node;ADD(mempool, node); //加入链表
}

版本二

  当然初始的内存池也存在较多的问题:会出现内存块越来越小的问题。
  提出按照不同的大小l来配固定大小的块。例如,假定最小的内存块为16Byte,可以进行32Byte、64Byte、128Byte、256Byte、512Byte、1024Byte。假设大于1024Byte为大内存块,交给系统进行分配和释放。其实先内存分配的过程中往往最难处理的就是这些小块内存块。这里引入小块大块的概念。

伪代码

// 伪代码
//节点结构体
struct memnode {void *addr;int size;int flag; //1 use, 0 freestruct memonde *next;
}//定义内存池
struct memnode *mempool;//重载malloc()
void *nmalloc(int size) {void * addr = search(usetable, size); //循环做if (addr = NULL) {void *addr = malloc(size);struct memnode *node;ADD(mempool, node); //加入链表}
}//重载free()
void nfree(void *addr) {struct memnode *node = search_from(addr);node->flag = 0;
}

版本二的方式仍然有一些问题,这里提出来。主要是查找速度慢,内存块不是连在一起的(无法合并成一个大块)会有间隙,后续我们会继续讨论。

总结

本文主要介绍了什么是内存池,内存池简单来说是一种动态内存分配与管理技术。其核心避免频繁的内存分配与释放,减少内存碎片。并举例在CS模型中的体现。并且介绍了内存池一个演变的过程,从最早的内存池雏形,到版本二较为实用的方式。

后续

后续还需继续对内存池进行分析,后续更精彩。

内存池 - 原理分析(一)相关推荐

  1. java并发包线程池原理分析锁的深度化

    java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素 ...

  2. Tomcat线程池监控及线程池原理分析

      目录         一.背景         二.tomcat线程池监控         三.tomcat线程池原理         四.总结 一.背景 我们都知道稳定性.高可用对于一个系统来讲 ...

  3. java 线程池原理分析

    一.为什么使用线程池 1.降低资源消耗,减少线程创建和销毁次数,每个工作线程可以重复利用,执行多个任务 2.可根据系统承受能力,调整工作线程的数目,防止消耗过多的内存 二.java 线程池使用 Exe ...

  4. Netty技术细节源码分析-Recycler对象池原理分析

    本文是该篇的修正版 本文的github地址:点此 该文所涉及的netty源码版本为4.1.6. Netty的对象池Recycler是什么 Recycler是Netty中基于ThreadLocal的轻量 ...

  5. jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

    数据库访问 访问数据库主要有以下几个步骤: 加载数据库驱动 创建数据库连接 执行访问操作并处理执行结果 关闭连接,释放资源 在每一次请求数据库都要经历上述过程,创建连接和释放资源也都是些重复性的动作, ...

  6. 【5】线程池原理分析

    目录 知识点1:并发包 1.(计数器)CountDownLatch 2.(屏障)CyclicBarrier 3.(计数信号量)Semaphore (1)案例 4.并发队列 5.阻塞队列与非阻塞队 (1 ...

  7. 一文看懂内存池原理及创建(C++实现)

    1. 什么是内存池 1.1 池化技术 池是在计算技术中经常使用的一种设计模式,其内涵在于:将程序中需要经常使用的核心资源先申请出来,放到一个池内,有程序自管理,这样可以提高资源的利用率,也可以保证本程 ...

  8. Java-Java中的线程池原理分析及使用

    文章目录 概述 线程池的优点 线程池的实现原理 线程池的使用 创建线程池 向线程池中提交任务 关闭线程池 合理的配置线程池 线程池的监控 概述 我们在上篇博文 Java-多线程框架Executor解读 ...

  9. Linux内存管理子系统——mmap内存映射原理分析(dax文件系统的mmap)

    Linux mmap分析 内核版本:linux-5.16 1. 虚拟内存概要及相关内容简介 内存映射是学习过操作系统的大家都耳熟能详的词,理解起来也很简单.所谓"映射"就是为一种事 ...

最新文章

  1. Python 生成器总结
  2. spring+mybatis事务的readonly属性无效
  3. Distinct Subsequences@LeetCode
  4. 朝聚眼科完成4亿元B轮融资,兰馨亚洲和阳光融汇投资...
  5. swift_044(Swift 计算属性和存储属性的概念以及使用)
  6. 用STM32实现:摄像头扫到二维码后提取二维码中的信息分别放到数组中
  7. office2013安装程序找不到office.zh-cn\officeMUI.xml 最新解决方案
  8. 第13天学习Java的笔记(类定义)
  9. Spring bean配置继承
  10. (ECC)椭圆曲线加密算法原理和C++实现源码
  11. Unknown encoder ‘libx264‘的解决方法
  12. 程序员被拖欠工资欲删库跑路,网友:还有没有职业素养
  13. 2019届互联网校招薪资盘点!
  14. 修改COCO评价指标 maxDets=[10,15,20]
  15. 汇川H5U模拟量输入模拟量转换 FC S_ITR
  16. Web 利用纯html和css画出一个android机器人
  17. Latex自动化学报模板学习和问题解决总结
  18. 2020最值得读的java书,2020年最值得读的10本书,你看过几本?
  19. “东信杯”广西大学第一届程序设计竞赛(同步赛)D、数论只会GCD 【博弈 分类讨论】...
  20. “人到中年”成网红,旺旺能否借此重返“旺季”?

热门文章

  1. 找最大ASCII字符
  2. Django报错 ValueError: The view didn‘t return an HttpResponse object. It returned None instead.
  3. 计算机、通信方向学习考证经验分享
  4. 为什么肯德基和麦当劳总是开在一起?
  5. Android中PopupWindow遮罩层的设置
  6. 无人值守安装操作系统
  7. Day 03-常用 Composition API_拉开序幕的setup()
  8. 这辈子你会遇见谁,早已命中注定
  9. 硬盘知识:硬盘中蓝盘、绿盘、黑盘、红盘有什么区别?
  10. 如果你还不懂区块链那就out了(三)--区块链3.0的优秀解决方案:Hyperledger fabric