Ngnix内存池——高并发实现高效内存管理

目录

一、高并发下传统方式的弊端

1、常用的内存操作函数

2、弊端一

3、弊端二

4、弊端三

5、弊端四

二、弊端解决之道

1、内存管理维度分析

2、内存管理组件选型

三、高并发内存管理最佳实践

1、内存池技术

2、内存池如何解决弊端

3、高并发内存池如何实现

四、高效内存池设计与实现

1、内存池的实现思路

2、Nginx内存池结构图

3、关键数据结构

4、ngx_pool_t结构示意图(大希奥未1024的池)

​5、Nginx内存池基本操作


一、高并发下传统方式的弊端

1、常用的内存操作函数

void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);

malloc  在内存的动态存储区中分配一块长度为size字节的连续区域返回该区域的首地址.

calloc  与malloc相似,参数size为申请地址的单位元素长度,nmemb为元素个数,即在内存中申请nmemb*size字节大小的连续地址空间.内存会初始化0

realloc  给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度.ptr 若为NULL,它就等同于 malloc.

2、弊端一

高并发时较小内存块使用导致系统调用频繁,降低了系统的执行效率。(系统调用不了解的,观看我博客里系统调用的一文)。

3、弊端二

频繁使用时增加了系统内存的碎片,降低内存使用效率

内部碎片 已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;

产生根源1.内存分配必须起始于可被 4、8 或 16 整除(视处理器体系结构而定)的地址

                  2.MMU的分页机制的限制

处理器

页大小

分页的级别

虚拟地址分级

x86

4KB

2

10+10+12

x86(extended)

4KB

1

10+22

x86(PAE)

4KB

3

2+9+9+12

x86-64

4KB

4

9+9+9+9+12

4、弊端三

没有垃圾回收机制,容易造成内存泄漏,导致内存枯竭

情形一:
void log_error(char *reason) 
{ 
    char *p1; 
    p1 = malloc(100); 
    sprintf(p1,"The f1 error occurred because of '%s'.", reason); 
    log(p1); 
}

情形二:  
int getkey(char *filename) 
{ 
    FILE *fp; 
    int key; 
    fp = fopen(filename, "r");
    fscanf(fp, "%d", &key); 
    //fclose(fp);
    return key; 
}

5、弊端四

内存分配与释放的逻辑在程序中相隔较远时,降低程序的稳定性

例如:程序1调用程序2,误认为传参过来的是指针,用完后,进行了释放

//程序1
ret get_stu_info(Student  * _stu) 
{ 
    char  * name= NULL; 
    name = getName(_stu->no);
    //处理逻辑
    if(name) 
    {
        free(name);
        name = NULL;
    }
}
//程序2
char stu_name[MAX];

char * getName(int stu_no)
{
    //查找相应的学号并赋值给 stu_name
     snprintf(stu_name,MAX,“%s”,name);
     return stu_name;
}

二、弊端解决之道

1、内存管理维度分析

2、内存管理组件选型

PtMalloc

(glibc 自带)

TcMalloc

JeMalloc

概念

Glibc 自带

Google 开源

Jason Evans

(FreeBSD著名开发人员)

性能

(一次malloc/free 操作)

300ns

50ns

<=50ns

弊端

锁机制降低性能,容易导致内存碎片

1%左右的额外内存开销

2%左右的额外内存开销

优点

传统,稳定

线程本地缓存,多线程分配效率高

线程本地缓存,多核多线程分配效率相当高

使用方式

Glibc 编译

动态链接库

动态链接库

谁在用

较普遍

safari、chrome等

facebook、firefox

适用场景

除特别追求高效内存分配以外的

多线程下高效内存分配

多线程下高效内存分配

三、高并发内存管理最佳实践

1、内存池技术

什么是内存池技术?

在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存,统一对程序所使用的内存进行统一的分配和回收。这样做的一个显著优点是,使得内存分配效率得到很大的提升。

2、内存池如何解决弊端

(1)、高并发时系统调用频繁,降低了系统的执行效率

        内存池提前预先分配大块内存,统一释放,极大的减少了malloc 和 free 等函数的调用。

(2)、频繁使用时增加了系统内存的碎片,降低内存使用效率

        内存池每次请求分配大小适度的内存块,避免了碎片的产生

(3)、没有垃圾回收机制,容易造成内存泄漏

        在生命周期结束后统一释放内存,完全避免了内存泄露的产生

(4)、内存分配与释放的逻辑在程序中相隔较远时,降低程序的稳定性

        在生命周期结束后统一释放内存,避免重复释放指针或释放空指针等情况

3、高并发内存池如何实现

高并发(High Concurrency是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。

高并发特点

(1)、响应时间短

(2)、吞吐量大

(4)、每秒响应请求数 QPS

(5)、并发用户数高:

内存池设计考虑

设计逻辑应该尽量简单,避免不同请求之间互相影响,尽量降低不同模块之间的耦合

内存池生存时间应该尽可能短,与请求或者连接具有相同的周期,减少碎片堆积和内存泄漏

四、高效内存池设计与实现

1、内存池的实现思路

(1)、对于每个请求或者连接都会建立相应的内存池,建立好内存池之后,我们可以直接从内存池中申请所需要的内存,不用去管内存的释放,当内存池使用完成之后一次性销毁内存池。

(2)、区分大小内存块的申请和释放,大于池尺寸的定义为大内存块,使用单独的大内存块链表保存,即时分配和释放;小于等于池尺寸的定义为小内存块,直接从预先分配的内存块中提取,不够就扩充池中的内存,在生命周期内对小块内存不做释放,直到最后统一销毁。

2、Nginx内存池结构图

3、关键数据结构

typedef struct 
{
    u_char               *last;         // 保存当前数据块中内存分配指针的当前位置
    u_char               *end;         // 保存内存块的结束位置
    ngx_pool_t           *next;      // 内存池由多块内存块组成,指向下一个数据块的位置
    ngx_uint_t            failed;      // 当前数据块内存不足引起分配失败的次数
} ngx_pool_data_t;
 
struct ngx_pool_s 
{
    ngx_pool_data_t       d;        // 内存池当前的数据区指针的结构体
    size_t                max;      // 当前数据块最大可分配的内存大小(Bytes)
    ngx_pool_t           *current;  // 当前正在使用的数据块的指针
    ngx_pool_large_t     *large;    // pool 中指向大数据块的指针(大数据快是指 size > max 
                                       的数据块)
};

4、ngx_pool_t结构示意图(大希奥未1024的池)



5、Nginx内存池基本操作

内存池创建、销毁和重置:

操作

函数

创建内存池

ngx_pool_t *  ngx_create_pool(size_t size);

销毁内存池

void ngx_destroy_pool(ngx_pool_t *pool);

重置内存池

void ngx_reset_pool(ngx_pool_t *pool);

内存池申请、释放和回收操作:

操作

函数

内存申请(对齐)

void *  ngx_palloc(ngx_pool_t *pool, size_t size);

内存申请(不对齐)

void *  ngx_pnalloc(ngx_pool_t *pool, size_t size);

内存申请(对齐并初始化)

void *  ngx_pcalloc(ngx_pool_t *pool, size_t size);

内存清除

ngx_int_t  ngx_pfree(ngx_pool_t *pool, void *p);

内存池申请、释放和回收操作:

操作

函数

内存申请(对齐)

void *  ngx_palloc(ngx_pool_t *pool, size_t size);

内存申请(不对齐)

void *  ngx_pnalloc(ngx_pool_t *pool, size_t size);

内存申请(对齐并初始化)

void *  ngx_pcalloc(ngx_pool_t *pool, size_t size);

内存清除

ngx_int_t  ngx_pfree(ngx_pool_t *pool, void *p);

源码代码详细见上传资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/751165.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot+vue+mysql+mybatis 二手交易平台

springbootvuemysqlmybatis 二手交易平台 相关技术 javaspringbootmybatismysqlvueelementui

十常侍乱政 | 第2集 | 愿领精兵五千,斩关入内,册立新君,诛杀宦党,扫清朝廷,以安天下 | 三国演义 | 逐鹿群雄

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;这篇博客是毛毛张分享三国演义文学剧本中的经典台词和语句&#xff0c;本篇分享的是《三国演义》第Ⅰ部分《群雄逐鹿》的第2️⃣集《十常侍乱政治》&am…

DigitalOcean Droplet 云主机新增内置第五代 Xeon CPU 机型

DigitalOcean 近期宣布&#xff0c;在其高级 CPU 服务器&#xff08;Premium CPU-Optimized Droplet&#xff09;队列中引入英特尔第五代Xeon可扩展处理器&#xff08;代号为 Emerald Rapids&#xff09;。作为英特尔产品线中的最新一代用于数据中心工作负载的处理器&#xff0…

干涉阵型成图参数记录【robust】

robust 这个玩意经常忘记&#xff0c;就是取2的时候是更加显示大尺度的结构&#xff0c;取-2更加显示小尺度结果&#xff0c;一般取0就是正常就好了

数学建模--lingo解决线性规划问题~~灵敏度分析的认识

目录 1.线性规划问题举隅 &#xff08;1&#xff09;问题介绍 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;灵敏度分析 &#xff08;4&#xff09;方法缺陷 &#xff08;5&#xff09;可行域&凸集 2.lingo的简单认识 &#xff08;1&#xff09;默认…

Halcon 如何根据特征过滤区域和XLD

一 如何跟进特征过滤区域和XLD dev_open_window(0,0,512,512,black,WindowHandle)read_image(Image,fabrik)threshold(Image,Region,128,255)connection(Region,ConnectedRegions)*根据面积范围[8000,9000] dev_display(Image)select_shape(ConnectedRegions,SelectedRegions,…

数据结构速成--树和二叉树

由于是速成专题&#xff0c;因此内容不会十分全面&#xff0c;只会涵盖考试重点&#xff0c;各学校课程要求不同 &#xff0c;大家可以按照考纲复习&#xff0c;不全面的内容&#xff0c;可以看一下小编主页数据结构初阶的内容&#xff0c;找到对应专题详细学习一下。 气死了…

springboot + Vue前后端项目(第二十记)

项目实战第二十记 写在前面1. 高德地图官网2. 开发文档3. 集成高德地图3.1 在public文件夹下创建config.js3.2 index.html&#xff08;在项目启动文件中引入外部的js&#xff09;3.3 点标记&#xff08;用点标记当前位置&#xff09;3.4 信息窗体&#xff08;点击当前位置&…

简易深度学习(1)深入分析神经元及多层感知机

一、神经元 单个神经元结构其实可以认为是一个线性回归模型。例如下图中 该神经元输入为三个特征&#xff08;x1&#xff0c;x2&#xff0c;x3&#xff09;&#xff0c;为了方便理解&#xff0c;大家可以认为每条线上都有一个权重和特征对应&#xff08;w1&#xff0c;w2&…

麒麟系统安装MySQL

搞了一整天&#xff0c;终于搞定了&#xff0c;记录一下。 一、背景 项目的原因&#xff0c;基于JeecgBoot开发的系统需要国产化支持&#xff0c;这就需要在电脑上安装MySQL等支撑软件。 国产化项目的操作系统多是麒麟系统&#xff0c;我的系统如下&#xff1a; arm64架构。…

ISSCC论文详解2024 34.2——双端口设计实现高面积利用的浮点/整数存算

本文将要介绍的文献主题为浮点存内计算&#xff0c;题目为《A 16nm 96Kb Integer/Floating-Point Dual-Mode-Gain-CellComputing-in-Memory Macro Achieving 73.3-163.3TOPS/W and 33.2-91.2TFLOPS/W for AI-Edge Devices》&#xff0c;下面本文将从文章基本信息与背景知识、创…

5.9k!一款清新好用的后台管理系统!【送源码】

今天给大家分享的开源项目是一个优雅清新后台管理系统——Soybean Admin。 简介 官方是这样介绍这个项目的&#xff1a; Soybean Admin 使用的是Vue3作为前端框架&#xff0c;TypeScript作为开发语言&#xff0c;同时还整合了NaiveUI组件库&#xff0c;使得系统具有高可用性和…

分页处理封装+分页查询题目列表

文章目录 1.sun-club-common封装分页1.com/sunxiansheng/subject/common/eneity/PageInfo.java2.com/sunxiansheng/subject/common/eneity/PageResult.java 2.sun-club-application-controller1.SubjectInfoDTO.java 继承PageInfo并新增字段2.SubjectController.java 3.sun-clu…

信息学奥赛初赛天天练-37-CSP-J2021阅读程序-质数、合数、约数、约数个数、约数和、增加质因数对约数个数、约数和的影响

PDF文档公众号回复关键字:20240627 质数 质数和合数是数学中对于自然数&#xff08;不包括0和1&#xff09;的两种重要分类 质数 (Prime Number) 一个大于1的自然数&#xff0c;除了1和它本身以外不再有其他因数的数称为质数 例如 2、3、5、7、11、13、17、19等都是质数 …

从RLHF到DPO再到TDPO,大模型对齐算法已经是「token-level」

在人工智能领域的发展过程中&#xff0c;对大语言模型&#xff08;LLM&#xff09;的控制与指导始终是核心挑战之一&#xff0c;旨在确保这些模型既强大又安全地服务于人类社会。早期的努力集中于通过人类反馈的强化学习方法&#xff08;RLHF&#xff09;来管理这些模型&#x…

【深度学习】python之人工智能应用篇--跨模态生成技术

跨模态生成技术概述 跨模态生成技术是一种将不同模态的数据&#xff08;如文本、图像、音频、视频等&#xff09;进行融合和转换的技术。其目标是通过将一个模态的数据作为输入&#xff0c;生成与之对应的另一个模态的输出。这种技术对于突破单一模态的局限性&#xff0c;提高…

数据库怎么同步

数据库要怎么同步呢&#xff0c;有很多方法&#xff0c;看你用什么数据库&#xff0c;如果是Sqlserver,你要数据库同步&#xff0c;那么可以使用自带的订阅发布&#xff0c;订阅发布应该是不错的方法&#xff0c;但是我上次要配置双向同步&#xff0c;它的对等发布好像没部署成…

力扣-和为K的子数组

题目-和为 K 的子数组 解法1&#xff1a;两层for循环 public class T560 {public static int subarraySum(int[] nums, int k) {int res 0;for (int i 0; i < nums.length; i) {int tempSum 0;for (int j i; j < nums.length; j) {tempSum nums[j];if (tempSum k)…

JetBrains IDEA 2024 无线重置免费 试用

注意&#xff1a;该文档只作为参考&#xff0c;若涉及到版权问题&#xff0c;请官方购买正版软件 Idea的使用&#xff0c;不是免费的。需要自己购买&#xff0c;获取证书才能使用&#xff0c;那么怎么无限试用30天呢&#xff1f; 免费试用操作&#xff1a; 文件删除 删除C:\…

揭秘数据合并的秘密:一文掌握一对一、多对一、多对多合并技巧与实战!

使用pd.merge()合并 类似 MySQL 中表和表直接的合并merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并每一列元素的顺序不要求一致1. 一对一合并 df1 = pd.DataFrame({"…