高并发服务器的设计--内存池的设计

华为OD机试 -简易内存池2(Java) | 机试题+算法思路+考点+代码解析 【2023】 请实现一个简易内存池根据请求命令完成内存分配和释放内存池支持两种操作命令REQUEST和RELEASE其格式为表示请求分配指定大小内存如果分配成功,返回分配到的内存首地址如果内存不足,或指定的大小为零则输出表示释放掉之前分配的内存释放成功无需输出如果释放不存在的首地址则输出error。 阅读详情
http://blog.youkuaiyun.com/xiaofei_hah0000/article/details/8977538

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能。
做服务器开发很多年了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢?
简单的回答就是QPS,并发数,但有时候想想也许也不对。
QPS与并发数是针对同样的业务而言的,业务不同,相同的服务器能承受的压力也会不同。
性能,也许可以打个俗点的比方:
服务器就是一艘船,性能就是船的容量,开的速度,行得是否稳当。
该用的用,该省的省。能用内存就别用IO,CPU则能少用就少用,相同的QPS,CPU和内存用的少点的性能就要比用的多点好,同样,QPS跑得多点的就比
跑得小点的性能要好,哪怕多用了点CPU和内存。
什么是性能的保障呢?
高效的事件模型,简单明了的业务架构,统一稳定的资源管理,外加纯熟的人员。
咱就从资源说起吧。
资源多半与IO有关,如果你看过我前面的文章,一定不会对连接池陌生,没错,连接是系统的一种IO资源,下面看看另一种IO资源:内存。

如果你看过apache, nginx之类服务器的代码,或者想入手,那么多半应该从内存管理开始。
与服务器性能息息相关,内存池的设计也追求快速与稳定,生命周期一般有下面三种:
global: 全局的内存,存放整个进程的全局信息。
conn: 每个连接的信息,从连接产生到关闭。
busi:业务相关的信息,伴随每个业务的产生到结束

下面定义一个简单的内存池:

  1. typedef struct yumei_mem_buf_s yumei_mem_buf_t;  
  2. typedef struct yumei_mem_pool_s yumei_mem_pool_t;  
  3.   
  4. struct yumei_mem_buf_s  
  5. {  
  6.     int                          size;  
  7.     char                        *pos;  
  8.     char                        *data;  
  9.     yumei_mem_pool_t            *pool;  
  10. };  
  11.   
  12. struct yumei_mem_pool_s  
  13. {  
  14.     int                          size;  
  15.     char                        *data;  
  16.     char                        *last;  
  17.     yumei_mem_pool_t            *next;  
  18.     yumei_mem_pool_t            *current;  
  19. };  
  20.   
  21. yumei_mem_pool_t* yumei_mem_pool_create( int block_size, int block_num );  
  22. int yumei_mem_pool_free( yumei_mem_pool_t  *pool );  
  23. yumei_mem_buf_t* yumei_mem_malloc( yumei_mem_pool_t   *pool, int size );  
  24. int yumei_mem_buf_free( yumei_mem_buf_t *buf );  

在每个连接开始的时候,创建连接唯一的内存池,存放IO数据,当要创建新业务时,创建业务内存池,业务处理完毕时释放内存池:

  1. typedef struct yumei_busi_s yumei_busi_t;  
  2.   
  3. struct yumei_busi_s  
  4. {  
  5.     yumei_mem_pool_t      *pool;  
  6.     ...  
  7.     ...  
  8.   
  9. }  
  10.   
  11. #define yumei_BUSI_MEM_BLOCL_SIZE 512  
  12. #define yumei_BUSI_MEM_BLOCK_NUM  32  
  13.   
  14. yumei_busi_t* yumei_busi_create()  
  15. {  
  16.     yumei_busi_t* busi;  
  17.     yumei_pool_t* pool;  
  18.     yumei_mem_buf_t* buf;  
  19.     int size;  
  20.   
  21.     pool = yumei_mem_pool_create( yumei_BUSI_MEM_BLOCL_SIZE, yumei_BUSI_MEM_BLOCK_NUM );  
  22.     if( !pool ){  
  23.         return 0;  
  24.     }  
  25.   
  26.     size = sizeof( yumei_busi_t );  
  27.     buf = yumei_mem_buf_malloc( pool, size );  
  28.   
  29.     if( !buf ){  
  30.         yumei_mem_pool_free( pool );  
  31.         return 0;  
  32.     }  
  33.   
  34.     busi = buf->data;  
  35.   
  36.     return busi;  
  37.   
  38. }  
  39.   
  40. #define YUMEI_BUSI_ERROR -1  
  41. #define YUMEI_BUSI_OK     0  
  42.   
  43. int yumei_busi_free( yumei_busi_t* busi )  
  44. {  
  45.     if( !busi ){  
  46.         return YUMEI_BUSI_ERROR;  
  47.     }  
  48.   
  49.     yumei_mem_pool_free( busi->pool );  
  50.   
  51.     return YUMEI_BUSI_OK;  
  52. }  

有些时候业务比较简单,一个连接仅对应一个业务或多个业务不是并行执行,这样的情况下,就不再需要业务内存池了,可以直接用连接内存池:

  1. yumei_busi_t* yumei_busi_create( yumei_conn_t* conn )  
  2. {  
  3.     yumei_busi_t* busi;  
  4.     yumei_pool_t* pool;  
  5.     yumei_mem_buf_t* buf;  
  6.     int size;  
  7.   
  8.     pool = conn->pool;  
  9.     if( !pool ){  
  10.         retur 0;  
  11.     }  
  12.   
  13.     size = sizeof( yumei_busi_t );  
  14.     buf = yumei_mem_buf_malloc( pool, size );  
  15.   
  16.     if( !buf ){  
  17.         yumei_mem_pool_free( pool );  
  18.         return 0;  
  19.     }  
  20.   
  21.     busi = buf->data;  
  22.   
  23.     return busi;  
  24.   
  25. }  
  26.   
  27. #define YUMEI_CONN_ERROR -1  
  28. #define YUMEI_CONN_OK     0  
  29.   
  30. int yumei_conn_close( yumei_conn_t* conn )  
  31. {  
  32.     if( !conn ){  
  33.         return YUMEI_CONN_ERROR;  
  34.     }  
  35.   
  36.     yumei_mem_pool_free( conn->pool );  
  37.   
  38.     return YUMEI_CONN_OK;  
  39. }  

知道内存池怎么用了,再来看看内部设计吧,pool 的四个元素里 size 对应 block_size, data和last 分别对应块的起始地址和可分配地址,next和current分别对应下块内存池和当前可用内存池。
在一些通用的服务器上还会看到另一个元素:large。 这个是争对一些大内存的分配,当不清楚业务到底需要多大内存的时候,large往往是必须的,这样内存池结构就变成这样:

  1. typedef struct yumei_mem_large_s yumei_mem_large_t;  
  2.   
  3. struct yumei_mem_large_s  
  4. {  
  5.     char                      *data;  
  6.     int                        size;  
  7.     yumei_mem_large_t         *next;  
  8. }  
  9.   
  10. struct yumei_mem_pool_s  
  11. {  
  12.     int                          size;  
  13.     char                        *data;  
  14.     char                        *last;  
  15.     yumei_mem_pool_t            *next;  
  16.     yumei_mem_pool_t            *current;  
  17.     yumei_mem_large_t           *large;  
  18. };  

对于一些特殊的业务,比如业务使用的内存大小都固定,且相近的时候,内存池就缩化成了固定大小的内存管理,其实是很简单了,这样的内存池可以绑定在连接上,且用完不用释放,留待下条连接复用,进一步节省开销。

简易的内存池实现 简单的内存池实现,已经应用到一个小项目中,使用方法看头文件吧,代码也不多. 立即下载

相关推荐

1.5元主控搞定高精度电流电压采集?STC8G1K08+INA180A3硬件设计全解析

本文详细解析了如何利用成本仅1.5元的STC8G1K08单片机与INA180A3电流检测放大器,构建一套高精度、低成本的电流电压采集系统。文章深入剖析了硬件设计精髓,包括利用MCU内部上拉电阻直驱数码管以节省成本、INA180A3的配置与计算,以及实现高频率采集并与上位机高速通信的软件策略,为嵌入式开发中的极致性价比设计提供了完整方案。

weixin_29166013的博客 601

【java】池技术--连接池 线程池 内存池 进程池等汇总分析

网站性能优化:在构建高性能网站时,可以使用 HTTP 连接池、数据库连接池、线程池等池技术,同时结合缓存(如 Redis 缓存、CDN 缓存)、异步编程(如 AJAX、异步 I/O)以及负载均衡(如反向代理、DNS 负载均衡)等技术,共同提高网站性能。大数据处理:在大数据处理场景中,可以使用线程池、进程池等并行计算技术,同时结合资源预留、负载均衡(如 Hadoop 分布式文件系统、Spark 调度器)等技术,以提高数据处理性能和资源利用率。通过限制工作线程或进程的数量,可以实现资源的有效利用和负载均衡。

DreamSun的博客 1740

matlab中高频变压器怎么找,干货|手把手教你绕制高频变压器

原标题:干货|手把手教你绕制高频变压器绕制一个变压器所需材料:磁芯、骨架、各种铜线、麦拉胶带。变压器参数:磁芯:EE22原边:134T(1-3脚),辅助:32T(5-4脚),输出:15T(10-9脚)原边电感:1380±10%uH漏感:≤44uH引脚分布图: 特别注意:绕制方法为网上下载,其中变压器绕制方法是对的,但其中存在着很多问题(比如,正规变压器的绕组的头和尾是要添加铁氟龙套管的,每一层之间...

weixin_30895121的博客 2127

java内存池_实现一个内存池管理的类方法

union obj{union obj* next;char p[1];};class MemoryPool{public:MemoryPool(){union obj* temp;m_memory.assign(5,(union obj*)NULL);for(int i=0;i{for(int j=0;j{temp = (obj*)malloc(sizeof(char)*(1<temp-&...

weixin_34652034的博客 260

从M350 RTK到E-Port:解锁大疆无人机多负载协同与PSDK V3开发新范式

本文深入解析了大疆M350 RTK无人机搭载的E-Port智能接口与全新的PSDK V3开发套件,如何共同实现多负载协同作业的范式转变。E-Port集成了供电与高速数据总线,而PSDK V3通过统一的设备模型与服务机制,大幅降低了第三方负载的开发门槛与集成复杂度,使构建如智能巡检等复杂空中作业系统变得更加高效和标准化。

3c4x5z6v7b的博客 167

手把手教你解决Kernel panic报错:init找不到的5种排查方法(附NFS挂载实战)

本文深入解析了Linux系统启动时出现“Kernel panic - not syncing: No working init found”报错的根本原因,并提供了五种系统性的排查方法。文章结合NFS挂载根文件系统的实战场景,详细阐述了从动态链接库依赖、内核引导参数、NFS权限配置、文件系统完整性到内核配置干扰的完整排查路径,帮助开发者快速定位并解决这一常见的系统启动故障。

weixin_29159995的博客 196

内存池的实现

内存池实现

qq_57041630的博客 815

奥比中光Dabai深度相机SDK在Ubuntu22.04的兼容性安装指南

本文详细指导如何在Ubuntu22.04系统上安装奥比中光Dabai深度相机的SDK。针对新旧版本不兼容的核心问题,重点推荐使用经过验证的v1.10.18版本SDK,并提供了从系统依赖检查、SDK下载安装、Python环境配置到编译测试的完整步骤,帮助用户成功解决安装难题并实现相机驱动。

j2k3l4的博客 1001

java设计高并发内存池_高并发服务器的设计--内存池的设计

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能。做服务器开发很多年了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢?简单的回答就是QPS,并发数,但有时候想想也许也不对。QPS与并发数是针对同样的业务而言的,业务不同,相同的服务器能承受的压力也会不同。性能,也许可以打个俗点的比方:服务器就是一艘船,性能就是船的容量,开的速度,行得是否稳当。该用的用,该省的省。能用内存...

weixin_33117513的博客 191

告别实车测试:手把手教你用Vector VT平台搭建OBC/DCDC的HIL测试台架

本文详细介绍了如何利用Vector VT平台搭建新能源汽车OBC/DCDC的HIL测试台架,涵盖硬件选型、模型部署到自动化测试的全流程。通过HIL仿真测试技术,工程师可以高效验证动力域关键部件,大幅缩短开发周期并降低成本,特别适合新能源汽车三电系统的开发验证。

weixin_42659194的博客 341

SAP PS模块预算控制实战:为什么你的采购订单金额和预算占用对不上?

本文深入解析SAP PS模块中采购订单金额与预算占用偏差的常见问题,揭示承诺成本与实际成本的分流处理机制。通过实战案例和六步定位法,提供发票拆分、跨年度预算等典型场景的解决方案,并分享预防性配置框架和最佳实践,帮助企业有效控制预算偏差。

weixin_30363981的博客 516

高并发服务器的设计--内存池的设计 .

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能。 做服务器开发很多年了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢? 简单的回答就是QPS,并发数,但有时候想想也许也不对。 QPS与并发数是针对同样的业务而言的,业务不同,相同的服务器能承受的压力也会不同。 性能,也许可以打个俗点的比方: 服务器就是一艘船,性能就是船的容量,开的速度,行得是否稳当。 该用

移动互联技术----酒歌 1265

MATLAB极坐标伪彩色圆图绘制之polarPcolor函数

polarPcolor函数介绍 我们经常在论文或期刊上看到如下图这种以色调冷暖代表数值大小的极坐标圆图, 而function [varargout] = polarPcolor(R,theta,Z,varargin)可以很好的帮助我们快速绘制这类极坐标圆图。它非常适合雷达或激光雷达的平面位置指示器。使用polarPcolor函数时,我们只需根据手中数据构造相应的二维矩阵Z即可,十分便捷。varargin值为绘制模式选择。R值为半径坐标一维矩阵,theta值为角坐标一维矩阵。 代码示例 这里使用了海洋表面耀光

qq_19512613的博客 1万+

java内存池实现_[置顶] 高并发服务器的设计--内存池的设计

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能。做服务器开发很多年了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢?简单的回答就是QPS,并发数,但有时候想想也许也不对。QPS与并发数是针对同样的业务而言的,业务不同,相同的服务器能承受的压力也会不同。性能,也许可以打个俗点的比方:服务器就是一艘船,性能就是船的容量,开的速度,行得是否稳当。该用的用,该省的省。能用内存...

weixin_32955455的博客 248

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java设计高并发内存池_高并发服务器-连接池的设计

高并发服务器-连接池的设计高并发服务器需要有一些池的设计,如内存池,连接池,数据库连接池。池(pool)的设计主要考虑到一些资源的频繁申请和释放,尤其是在高并发的服务器中,几万甚至几十万并发每秒,设计人员不得不去考虑这些。比如数据库连接池(sql pool),是通过TCP来通信的,属于IO类,有一定的延时,在高并发系统中频繁的创建会严重影响系统性能。内存( mem )的分配是要涉及锁( mutex...

weixin_35514865的博客 198

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

本文将深入探讨内存池的优化实现,作为无锁队列和线程池的关键组件,并结合一个针对特定场景的线程池设计,以高并发 Web 服务器任务调度为例,进一步优化性能

本文将深入探讨内存池的优化实现,作为无锁队列和线程池的关键组件,并结合一个针对特定场景的线程池设计,以高并发 Web 服务器任务调度为例,进一步优化性能。内存池将解决动态分配的开销和碎片问题,线程池将集成内存池、无锁环形缓冲区、任务优先级、任务窃取等特性,针对服务器场景优化吞吐量和延迟。内存池是一种预分配内存的机制,用于减少动态分配(如 new/delete)的开销和内存碎片。以下是一个针对 Web 服务器的线程池实现,集成内存池、无锁环形缓冲区、优先级调度和动态线程管理。

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 877

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

内存业务[置顶] 高并发服务器的设计--内存池的设计

题记:写这篇博客要主是加深自己对内存业务的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。 typedef struct yumei_mem_buf_s yumei_mem_buf_t; typedef struct yumei_mem_pool_s yumei_mem_pool_t; struct yumei_mem_buf_s { int size; char *p...

weixin_30610755的博客 96

Linux(服务器编程3.3):---内存池设计(仿Nginx内存池设计c实现)

一、线程池的引入 服务器在高并发下,有大量的客户端连接时,服务器要解析客户端发来的数据,就需要频繁对内存进行申请和释放,使得服务器性能的降低和内存的碎片化增多。 开源的比较好用的内存池有: 1,tcmalloc:MySQL使用的 ; 2,jemalloc:Tomcat使用的 ; 3,Nginx实现的内存池。 这里是仿照nginx实现的内存池; 二、内存池的设计 我们该如何实现内存池? 内存池是一个组件,做出来以后,提供API给别人使用,在此提一个组件实现的通用方法: 1,宏定义来处理

Daback01的博客 628

软件开发中的实时内存池管理策略设计与性能优化

内存池是一种预先分配并管理内存的机制,通过集中化管理内存块,减少频繁的系统调用和内存碎片问题。在实时系统、高性能服务器和嵌入式开发中,内存池技术被广泛用于提升内存分配效率和程序性能。

jie_kou的博客 873

高并发服务器的设计--连接池的设计

高并发服务器需要有一些池的设计,如内存池,连接池,数据库连接池。 池(pool)的设计主要考虑到一些资源的频繁申请和释放,尤其是在高并发的服务器中,几万甚至几十万并发每秒,设计人员不得不去考虑这些。 比如数据库连接池(sql pool),是通过TCP来通信的,属于IO类,有一定的延时,在高并发系统中频繁的创建会严重影响系统性能。 内存( mem )的分配是要涉及锁( mutex )的,有锁就

xiaofei chain 7800

高并发服务器-连接池的设计

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33856370的博客 181

18张图揭秘高性能Linux服务器内存池技术是如何实现的

从这里的设计可以看出,我们的内存池其实是不会提供类似free这样的内存释放函数的,如果要释放内存,那么会一次性将整个内存池释放掉,这一点和通用的内存分配器是不一样。其次在于定位,我们自己实现的malloc其实也是定位通用性的,通用性的内存分配器设计实现往往比较复杂,但是内存池技术就不一样了,内存池技术专用于某个特定场景,以此优化程序性能,但内存池技术的通用性是很差的,在一种场景下有很高性能的内存池基本上没有办法在其它场景也能获得高性能,甚至根本就不能用于其它场景,这就是内存池这种技术的定位。

2401_86394091的博客 1851

Nginx 原理和架构

Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器。Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。 Nginx 的整体架构 Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处...

albon arith 7万+
上一篇: Java中的字符串翻转
下一篇: MyBatis 缓存机制深度解剖 / 自定义二级缓存
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值