Nginx内存池相关源码剖析(六)外部资源释放和内存池销毁

ngx_destroy_pool函数

先执行回调函数释放所有的外部资源,然后free释放所有的大块内存和小块内存。

// 释放外部资源,销毁内存池
void
ngx_destroy_pool(ngx_pool_t *pool)
{ngx_pool_t          *p, *n;ngx_pool_large_t    *l;ngx_pool_cleanup_t  *c;for (c = pool->cleanup; c; c = c->next) {if (c->handler) { // 执行回调函数,释放用户的外部资源ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,"run cleanup: %p", c);c->handler(c->data);}}#if (NGX_DEBUG) // 忽略不看/** we could allocate the pool->log from this pool* so we cannot use this log while free()ing the pool*/for (l = pool->large; l; l = l->next) {ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);}for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,"free: %p, unused: %uz", p, p->d.end - p->d.last);if (n == NULL) {break;}}#endiffor (l = pool->large; l; l = l->next) {if (l->alloc) {// 释放每一个大块内存ngx_free(l->alloc);}}for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) { // 释放每一个小块内存ngx_free(p);if (n == NULL) {break;} }
}

回调函数释放外部资源

外部资源是什么?

举两个例子:

假设Nginx在处理一个HTTP请求时需要打开一个文件,并读取其中的内容。这个文件描述符就是一个外部资源,因为它不是由Nginx内存池直接管理的。Nginx可能会在内存池中分配一个结构体来存储与这个请求相关的状态信息,这个结构体中可能包含一个指向文件描述符的指针。

当请求处理完毕,Nginx准备释放与这个请求相关的内存池时,如果仅仅释放内存池中的内存块,那么文件描述符并不会被自动关闭,这就会导致资源泄漏。为了避免这种情况,Nginx可以在创建内存池时注册一个回调函数,这个回调函数的职责就是在内存池被销毁时关闭文件描述符。

若有一个如下图的结构体,其使用Nginx内存池存放在小块内存中,即指针p和其他成员在内存池中,但是p指向了一个用户自己开辟的内存地址并存储了“hello world”。这样在内存池销毁时,释放了存储变量stData的内存,指针p被释放,但是其指向的内存地址并未释放,导致了内存泄漏。 

想要释放诸如此类的外部资源,需要对外部资源预置一个对应的资源释放函数,通过回调函数及函数指针来实现。

保存在内存池头信息中的 cleanup 链表

链表的结构体如下:

typedef void (*ngx_pool_cleanup_pt)(void *data); // 回调函数 函数指针typedef struct ngx_pool_cleanup_s  ngx_pool_cleanup_t; // 预置一个资源释放的函数struct ngx_pool_cleanup_s { // 本清理信息,也会分配在小块内存的内存池上ngx_pool_cleanup_pt   handler; // 回调函数 函数指针  保存预先设置的回调函数void                 *data; // 资源地址ngx_pool_cleanup_t   *next; // 很多释放资源的动作,做成链表
};

存放示意图:

注:上图中的cleanup头信息应和大块内存头信息一样,都存放在小块内存池中。 

 回调函数链表使用ngx_pool_cleanup_add函数进行创建和插入。

ngx_pool_cleanup_add函数

代码及注释:

ngx_pool_cleanup_t *
ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
{ngx_pool_cleanup_t  *c;c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t)); // cleanup头信息放到小块内存池中if (c == NULL) {return NULL;}if (size) { // size是传递给回调函数的参数的大小c->data = ngx_palloc(p, size); // 释放内存,通过用户手动赋值if (c->data == NULL) {return NULL;}} else { // 回调函数不要参数c->data = NULL;}c->handler = NULL; // handler通过用户手动赋值c->next = p->cleanup; // 新的清除信息节点,头插法串到cleanup节点上p->cleanup = c;ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);return c;
}

cleanup使用示例:

在destroy函数中, 通过函数指针调用release,并传入参数:

总结:

destroy的释放顺序:

1、通过回调函数链表,释放外部资源

2、释放大块内存

3、释放小块内存

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑录制视频软件推荐,帮你找到合适的那一款

随着科技的不断发展,录制视频已成为人们在学习、工作和生活中不可或缺的一部分。电脑录制视频软件作为实现这一目标的重要工具,已经越来越受到用户的青睐。本文将详细介绍三种常用的电脑录制视频软件,帮助用户更好地理解和使用这些工具&#…

高负压采样器

你的未来是你自己创造的,你的路是你自己选择的。走向成功,需要你的勇气和决心,成功不是得到多少,而是付出了多少。当你还在努力时,不要忘记身边的风景——鹤壁永成在你身边 一、高负压瓦斯采取器的用途: 高…

MS SQL Server partition by 函数实战 统计与输出

目录 需求 范例运行环境 表及视图样本设计 数据统计实现 小结 需求 假设有一课程项目,我们需要统计该项目中的课件数量,并提取课程信息,如课程标题名称、排序号等,如果使用 GROUP BY 聚合函数,则只能统计返回课件…

Java集合进阶——泛型

1.泛型 介绍&#xff1a; 泛型可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。 应用场景&#xff1a; 如果在定义类、方法、接口的时候&#xff0c;如果类型不确定&#xff0c;就可以使用泛型。 格式&#xff1a; <数据类型> 注意&#xff1a; 泛型只支持引…

数字化社交的引擎:解析Facebook的影响力

Facebook&#xff0c;作为全球最大的社交媒体平台&#xff0c;已经深深地融入了我们的日常生活和文化中。它不仅仅是一个简单的社交工具&#xff0c;更是一个复杂的数字生态系统&#xff0c;影响着我们的社交模式、文化认同以及信息获取方式。在这篇文章中&#xff0c;我们将深…

【华为】Telnet实验配置

【华为】Telnet 实验配置 应用场景三种认证方式配置注意事项拓扑无认证&#xff08;None&#xff09;交换机配置顺序Telnet ServerTelnet Client测试 密码认证&#xff08;Password&#xff09;配置顺序Telnet ServerTelnet Client测试 AAA认证&#xff08;scheme&#xff09;配…

使用TomCat在idea写一个可以实现分页查询的前后端学生项目04.12

使用TomCat在idea写一个前后端学生项目04.12项目包-CSDN博客 在前端界面需要引入的插件&#xff1a; 在该网站下载需要的插件 Maven Repository: Search/Browse/Explore (mvnrepository.com)https://mvnrepository.com/ 分页查询&#xff1a; 在前端jsp页面使用c:forEach c:…

WordPress 多站点切换域名完整指南:详细步骤和注意事项

因为公司的需要&#xff0c;需要对 WordPress 多站点进行域名切换, 一开始我也找了相关的方案和教程&#xff0c;但是很可惜&#xff0c;国内这一块网上的资料几乎为0&#xff0c;所以我把实现的过程写了一篇文章分享出来&#xff0c;为后来的人铺路。 开始之前&#xff0c;先…

BCLinux8U6系统基线加固致无法su的问题分析

本文对BCLinux8U6系统进行基线加固致无法su的问题分析。 一、问题现象 对BCLinux8U6系统进行基线加固&#xff0c;su切换用户失败&#xff0c;报错信息如下&#xff1a; [ABCDlocalhost ~]$ su - 密码&#xff1a; su: 模块未知 二、问题分析 1、错误排查 出错前&#xf…

el-table使用show-summary合计,但只需要合并某一列

el-table使用show-summary合计&#xff0c;但只需要合并某一列 这里有两种方法&#xff0c;一种是网上的&#xff0c;我会引用他的链接给你们看。 一种是我自己看源码发现的 方法一 这个就是方法一的链接 点击我跳转方法一 方法二 不需要计算的列 去掉prop 然后用插槽显示即可…

设计模式代码实战-抽象工厂模式

1、问题描述 小明家新开了两个工厂用来生产家具&#xff0c;一个生产现代风格的沙发和椅子&#xff0c;一个生产古典风格的沙发和椅子&#xff0c;现在工厂收到了一笔订单&#xff0c;请你帮他设计一个系统&#xff0c;描述订单需要生产家具的信息。 输入试例&#xff1a; 3 …

MonkeyRunner在自动化测试里的应用场景

MonkeyRunner是Android提供的一个自动化测试工具&#xff0c;主要用于对Android设备或模拟器进行功能和压力测试。以下是一些MonkeyRunner在自动化测试中的应用场景及实例代码&#xff1a; 基本操作测试 点击屏幕上的特定位置或元素。 模拟滑动和手势操作。 发送按键事件。…

Kubernetes(K8S)集群搭建-node节点配置

1.开始操作之前要先关闭防火墙&#xff0c;SELinux&#xff0c;swap分区 关闭防火墙 sudo systemctl stop firewalld禁用SELinux sudo setenforce 0 # 临时禁用 sudo sed -i s/^SELINUXenforcing$/SELINUXper…

【黑马头条】-day08平台管理-用户敏感词管理-自媒体文章人工审核

文章目录 平台管理1 前端静态资源导入1.1 配置heimi-leadnews-admin.conf1.2 配置nginx.conf 2 管理员微服务的搭建2.1 创建管理员微服务2.2 创建admin表2.3 导入表实体类2.4 创建对应实体类的mapper2.5 创建启动类2.6 创建配置文件bootstrap.yml2.7 在nacos中配置数据库等 3 登…

C++从入门到精通——类的6个默认成员函数之赋值运算符重载

赋值运算符重载 前言一、运算符重载定义实例注意要点 二、赋值运算符重载赋值运算符重载格式赋值运算符重载要点重载要点传值返回和传址返回要点 三、前置和后置重载 前言 类的6个默认成员函数&#xff1a;如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么…

Vue3 笔记

vue3笔记 1. Vue3简介1.1. 【性能的提升】1.2.【 源码的升级】1.3. 【拥抱TypeScript】1.4. 【新的特性】 2. 创建Vue3工程2.1. 【基于 vue-cli 创建】2.2. 【基于 vite 创建】(推荐)2.3. 【一个简单的效果】 3. Vue3核心语法3.1. 【OptionsAPI 与 CompositionAPI】Options API…

记第一次踩坑Gradle

今天有个项目只能使用Gradle编译&#xff0c;没办法了&#xff0c;尝试吧。 先去下载了最新版本的Gradle&#xff0c;然后配置好了环境变量&#xff0c;可以在命令行使用gradle命令了。 然后打开项目开始操作一番&#xff0c;但是上来就傻眼了。 我白下载了&#xff0c;又重新下…

30元腾讯云服务器搭建幻兽帕鲁Palworld多人联机游戏,畅玩

幻兽帕鲁太火了&#xff0c;官方palworld服务器不稳定&#xff1f;不如自建服务器&#xff0c;基于腾讯云幻兽帕鲁服务器成本32元全自动部署幻兽帕鲁服务器&#xff0c;超简单有手就行&#xff0c;全程自动化一键部署10秒钟即可搞定&#xff0c;无需玩家手动部署幻兽帕鲁游戏程…

Hive 解决数据倾斜方法

数据倾斜问题&#xff0c; 通常是指参与计算的数据分布不均&#xff0c; 即某个 key 或者某些 key 的数据量远超其他 key&#xff0c; 导致在 shuffle 阶段&#xff0c; 大量相同 key 的数据被发往同一个 Reduce&#xff0c; 进而导致该 Reduce 所需的时间远超其他 Reduce&…

Elasticsearch可视化工具:kibana + elasticsearch-head

kibana 下载 地址&#xff1a;https://www.elastic.co/cn/downloads/kibana 下载别的版本&#xff1a;https://www.elastic.co/cn/downloads/past-releases#kibana 将Kibana安装包解压缩 进入config目录&#xff0c;在kibana.yml中添加es服务器地址。&#xff08;如果之前没…