Nginx内存池相关源码剖析(四)大块内存分配和释放逻辑

2024-04-16 16:44

本文主要是介绍Nginx内存池相关源码剖析(四)大块内存分配和释放逻辑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

与小块内存不同,大块内存通常指的是那些大小较大、分配和释放频率相对较低的内存块。

ngx_palloc_large函数

当Nginx需要分配一块大块内存时,它通常会直接调用操作系统的内存分配函数(如malloc、calloc或posix_memalign等)。这些函数会根据请求的大小在操作系统的内存空间中寻找一块合适的连续内存区域,并将其分配给Nginx使用。由于大块内存的大小通常较大,因此操作系统能够更容易地找到满足需求的连续内存空间。

在分配大块内存时,Nginx通常不会过多进行额外的内存池检查或预分配操作。这是因为大块内存的分配和释放相对较为罕见,且频繁地进行内存池检查会增加不必要的开销。

源码及注释:

static void *ngx_palloc_large(ngx_pool_t *pool, size_t size)
{void              *p;ngx_uint_t         n;ngx_pool_large_t  *large; // 结构体中有下块地址next和本块内存地址allocp = ngx_alloc(size, pool->log); // malloc 开辟大块内存 if (p == NULL) {return NULL;}n = 0;for (large = pool->large; large; large = large->next) {// 复用大块内存头信息体链表中,现有的空头信息体// alloc为空是先前通过pfree函数释放的// 此举是为了不去创建新的大内存头信息体,复用之前归还的大内存头信息体if (large->alloc == NULL) { large->alloc = p;return p;}if (n++ > 3) { // 防止找的次数太多浪费时间break;}}// 在小块内存池中,存放大块内存的头信息体large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1); if (large == NULL) { // 没有开辟成功ngx_free(p); // 把新创建的大块内存空间free掉return NULL;}large->alloc = p; // 头结点记录大块内存的地址信息large->next = pool->large; // 大块内存头信息体 头插法进链表pool->large = large;return p;
}

大块内存结构示意图:

ngx_alloc内存分配函数

ngx_alloc也是平台相关的alloc函数,不必纠结:

ngx_pfree大块内存释放函数

ngx_int_t
ngx_pfree(ngx_pool_t *pool, void *p) // 释放大块内存,不释放小块内存
{ngx_pool_large_t  *l;for (l = pool->large; l; l = l->next) {if (p == l->alloc) {ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,"free: %p", l->alloc);ngx_free(l->alloc); // 可理解为free函数,释放内存l->alloc = NULL; // 头信息体中地址域置空return NGX_OK; // #define  NGX_OK          0}}return NGX_DECLINED; // #define  NGX_DECLINED   -5
}

ngx_free——平台相关的free函数

总结

Nginx对于大块内存是调用系统的内存分配函数,然后将内存地址通过信息结构体进行管理。

当Nginx不再需要一块大块内存时,它会调用操作系统的内存释放函数(如free)来将内存归还给操作系统。与分配过程类似,Nginx在释放大块内存时也不会进行额外的内存池管理操作。相反,它会依赖于操作系统的内存管理机制来自动处理内存碎片和回收工作。

相对于小块内存的只有分配逻辑没有释放逻辑,大块内存两者都有。

这篇关于Nginx内存池相关源码剖析(四)大块内存分配和释放逻辑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/909345

相关文章

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

mybatisplus的逻辑删除过程

《mybatisplus的逻辑删除过程》:本文主要介绍mybatisplus的逻辑删除过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录myBATisplus的逻辑删除1、在配置文件中添加逻辑删除的字段2、在实体类上加上@TableLogic3、业务层正常删除即

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置