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

相关文章

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

JavaScript Array.from及其相关用法详解(示例演示)

《JavaScriptArray.from及其相关用法详解(示例演示)》Array.from方法是ES6引入的一个静态方法,用于从类数组对象或可迭代对象创建一个新的数组实例,本文将详细介绍Array... 目录一、Array.from 方法概述1. 方法介绍2. 示例演示二、结合实际场景的使用1. 初始化二

Nginx指令add_header和proxy_set_header的区别及说明

《Nginx指令add_header和proxy_set_header的区别及说明》:本文主要介绍Nginx指令add_header和proxy_set_header的区别及说明,具有很好的参考价... 目录Nginx指令add_header和proxy_set_header区别如何理解反向代理?proxy

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

Nginx配置location+rewrite实现隐性域名配置

《Nginx配置location+rewrite实现隐性域名配置》本文主要介绍了Nginx配置location+rewrite实现隐性域名配置,包括基于根目录、条件和反向代理+rewrite配置的隐性... 目录1、配置基于根目录的隐性域名(就是nginx反向代理)2、配置基于条件的隐性域名2.1、基于条件

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

Ubuntu中Nginx虚拟主机设置的项目实践

《Ubuntu中Nginx虚拟主机设置的项目实践》通过配置虚拟主机,可以在同一台服务器上运行多个独立的网站,本文主要介绍了Ubuntu中Nginx虚拟主机设置的项目实践,具有一定的参考价值,感兴趣的可... 目录简介安装 Nginx创建虚拟主机1. 创建网站目录2. 创建默认索引文件3. 配置 Nginx4

Java逻辑运算符之&&、|| 与&、 |的区别及应用

《Java逻辑运算符之&&、||与&、|的区别及应用》:本文主要介绍Java逻辑运算符之&&、||与&、|的区别及应用的相关资料,分别是&&、||与&、|,并探讨了它们在不同应用场景中... 目录前言一、基本概念与运算符介绍二、短路与与非短路与:&& 与 & 的区别1. &&:短路与(AND)2. &:非短