Ubuntu 下 nginx-1.24.0 源码分析 - NGX_MAX_ALLOC_FROM_POOL
NGX_MAX_ALLOC_FROM_POOL
定义在 src\core\ngx_palloc.h
#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)
在 src/os/unix/ngx_alloc.h
extern ngx_uint_t ngx_pagesize;这个全局变量定义在
src\os\unix\ngx_alloc.c 中
ngx_uint_t ngx_pagesize;
在 src/os/unix/ngx_posix_init.c
ngx_int_t ngx_os_init(ngx_log_t *log) {ngx_time_t *tp;ngx_uint_t n; #if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)long size; #endif#if (NGX_HAVE_OS_SPECIFIC_INIT)if (ngx_os_specific_init(log) != NGX_OK) {return NGX_ERROR;} #endifif (ngx_init_setproctitle(log) != NGX_OK) {return NGX_ERROR;}ngx_pagesize = getpagesize();这里被赋值
getpagesize函数用于获取系统的内存页大小(page size)。内存页是操作系统管理内存的基本单位,通常以字节为单位。
不同的操作系统和硬件架构可能会有不同的页大小,常见的页大小有 4KB、8KB、16KB 等。
getpagesize函数返回系统的页大小,单位为字节(bytes)为了使用
getpagesize函数,你需要包含以下头文件:#include <unistd.h>
在第一次使用时(main 函数中首次使用 ngx_create_pool)
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;这里 还未执行 ngx_os_init 函数,ngx_pagesize 还未被赋值(初始值为0,64 位无符号整数 - 1 = 18446744073709551615)
所以这里 p->max 的值是 size 的值
NGX_MAX_ALLOC_FROM_POOL 为什么要设置为 ngx_pagesize - 1?
避免跨页分配
a. 内存页的概念
- 操作系统以页(page)为单位管理内存,常见的页大小为 4KB(4096 字节)或 8KB(8192 字节)。
- 分配内存时,操作系统通常会按页分配,即使只需要少量内存,也会分配整个页。
b. 跨页分配的问题
- 如果从内存池中分配的内存块大小接近或等于一页(如 4096 字节),可能会导致跨页分配。
- 跨页分配会增加内存管理的复杂性,并可能导致性能下降。例如:
- 缓存未命中率增加:数据分布在多个缓存行中,访问效率降低。
- 内存对齐问题:跨页分配可能导致未对齐访问,影响性能。
- 将最大分配大小限制为
ngx_pagesize - 1,可以确保分配的内存块始终位于单个页内,避免跨页问题。- 例如,如果页大小为 4096 字节,则
NGX_MAX_ALLOC_FROM_POOL的值为 4095 字节,确保分配的内存不会跨越页边界。
提高内存利用率
a. 小块内存分配
- Nginx 的内存池主要用于分配小块内存(如 HTTP 请求头、连接上下文等)。
- 这些小块内存的大小通常远小于
ngx_pagesize,因此将最大分配大小限制为ngx_pagesize - 1可以充分利用内存池的空间。b. 大块内存分配
- 如果需要分配的内存大小超过
ngx_pagesize - 1,Nginx 会使用单独的大块内存分配机制(通过large链表管理)。- 这种设计可以避免大块内存占用内存池空间,从而提高内存池的利用率。
简化内存管理
a. 内存池的设计目标
- 内存池的设计目标是高效地管理小块内存分配。
- 如果允许从内存池中分配过大的内存块,可能会增加内存池的复杂性。例如:
- 需要额外的链表或数据结构来跟踪大块内存的使用情况。
- 剩余的内存空间可能不足以满足其他分配请求,导致内存浪费。
b. 分离小块和大块内存
- 通过将最大分配大小限制为
ngx_pagesize - 1,可以将小块内存和大块内存的管理逻辑分离:
- 小块内存直接从内存池中分配,管理简单高效。
- 大块内存通过单独的分配机制(如
malloc或ngx_alloc)进行管理,避免干扰内存池。
相关文章:
Ubuntu 下 nginx-1.24.0 源码分析 - NGX_MAX_ALLOC_FROM_POOL
NGX_MAX_ALLOC_FROM_POOL 定义在 src\core\ngx_palloc.h #define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1) 在 src/os/unix/ngx_alloc.h extern ngx_uint_t ngx_pagesize; 这个全局变量定义在 src\os\unix\ngx_alloc.c 中 ngx_uint_t ngx_pagesize; 在 src/os/unix/ngx_…...
PyQt6/PySide6 的 SQL 数据库操作(QtSql)
一、核心组件架构 1.1 QtSql模块构成 QSqlDatabase:数据库连接管理(支持连接池)QSqlQuery:SQL语句执行与结果遍历QSqlTableModel:可编辑的表格数据模型QSqlQueryModel:只读查询结果模型QSqlRelationalTab…...
利用IDEA将Java.class文件反编译为Java文件:原理、实践与深度解析
文章目录 引言:当.class文件遇到源代码缺失第一章:反编译技术基础认知1.1 Java编译执行原理1.2 反编译的本质1.3 法律与道德边界 第二章:IDEA内置反编译工具详解2.1 环境准备2.2 三步完成基础反编译2.3 高级反编译技巧2.3.1 调试模式反编译2.…...
Kafka偏移量管理全攻略:从基础概念到高级操作实战
#作者:猎人 文章目录 前言:概念剖析kafka的两种位移消费位移消息的位移位移的提交自动提交手动提交 1、使用--to-earliest重置消费组消费指定topic进度2、使用--to-offset重置消费offset3、使用--to-datetime策略指定时间重置offset4、使用--to-current…...
【R语言】GitHub Copilot安装-待解决
参考: 文章目录...
软件定义汽车时代的功能安全和信息安全
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活…...
qt的QSizePolicy的使用
使用 QSizePolicy 设置控件的伸缩因子 在 Qt 中,QSizePolicy 控制 控件如何在布局中伸缩。如果想要影响控件的大小调整行为,可以通过 QSizePolicy::setHorizontalStretch() 和 QSizePolicy::setVerticalStretch() 设置伸缩因子。 基本用法 假设我们有一个…...
简单几个步骤完成 Oracle 到金仓数据库(KingbaseES)的迁移目标
作为国产数据库的领军选手,金仓数据库(KingbaseES)凭借其成熟的技术架构和广泛的市场覆盖,在国内众多领域中扮演着至关重要的角色。无论是国家电网、金融行业,还是铁路、医疗等关键领域,金仓数据库都以其卓…...
DeepSeek自动化写作软件
DeepSeek写作软件的三大核心功能 对于内容创作者来说,写作不仅是表达思想的过程,更是一项需要投入大量时间和精力的任务。面对日益增长的内容需求,写作效率低下、内容质量不高等问题,常常让创作者感到焦虑。而 DeepSeek 写作软件…...
【kafka系列】Kafka如何实现高吞吐量?
目录 1. 生产者端优化 核心机制: 关键参数: 2. Broker端优化 核心机制: 关键源码逻辑: 3. 消费者端优化 核心机制: 关键参数: 全链路优化流程 吞吐量瓶颈与调优 总结 Kafka的高吞吐能力源于其生…...
learn_pytorch03
第三章 深度学习分为如下几个步骤 1:数据预处理,划分训练集和测试集 2:选择模型,设定损失函数和优化函数 3:用模型取拟合训练数据,并在验证计算模型上表现。 接着学习了一些数据读入 模型构建 损失函数的构…...
机器学习:k近邻
所有代码和文档均在golitter/Decoding-ML-Top10: 使用 Python 优雅地实现机器学习十大经典算法。 (github.com),欢迎查看。 K 邻近算法(K-Nearest Neighbors,简称 KNN)是一种经典的机器学习算法,主要用于分类和回归任务…...
redis之lua实现原理
文章目录 创建并修改Lua环境Lua环境协作组件伪客户端lua scripts字典 EVAL命令的实现定义脚本函数执行脚本函数 EVALSHA命令的实现脚本管理命令的实现SCRIPT FLUSHSCRIPTEXISTSSCRIPT LOADSCRIPT KILL 脚本复制复制 EVAL命令、SCRIPT FLUSH命令和SCRIPT LOAD命令* 复制EVALSHA命…...
[Android] 【汽车OBD软件】Torque Pro (OBD 2 Car)
[Android] 【汽车OBD软件】Torque Pro (OBD 2 & Car) 链接:https://pan.xunlei.com/s/VOIyKOKHBR-2XTUy6oy9A91yA1?pwdm5jm# 获取 OBD 故障代码、汽车性能数据等等。Torque 使用连接到您的 OBD2 发动机管理/ECU 的 OBD II 蓝牙适配器。…...
安全问答—安全的基本架构
前言 将一些安全相关的问答进行整理汇总和陈述,形成一些以问答呈现的东西,加入一些自己的理解,欢迎路过的各位大佬进行讨论和论述。很多内容都会从甲方的安全认知去进行阐述。 1.安全存在的目的? 为了支持组织的目标、使命和宗…...
Java 运行时常量池笔记(详细版
📚 Java 运行时常量池笔记(详细版) Java 的运行时常量池(Runtime Constant Pool)是 JVM 方法区的一部分,用于存储编译期生成的字面量和符号引用。它是 Java 类文件常量池的运行时表示,具有动态…...
mysql增加字段操作以及关键字报错
修改mysql DDL语言 修改代码中domain 修改mapper中信息 java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near index, date, scroll_id, shard_ser…...
Wireshark 输出 数据包列表本身的值
在 Wireshark 中,如果你想输出数据包列表本身的值(例如,将数据包的摘要信息、时间戳、源地址、目的地址等导出为文本格式),可以使用 导出为纯文本文件 的功能。以下是详细步骤: 步骤 1:打开 Wir…...
日常开发中,使用JSON.stringify来实现深拷贝的坑
使用JSON.stringify的方式来实现深拷贝的弊端 弊端一:无法拷贝NaN、Infinity、undefined这类值 无法拷贝成功的原因: 对于JSON来说,它支持的数据类型只有null、string、number、boolean、Object、Array,所以对于它不支持的数据类…...
【探商宝】:大数据与AI赋能,助力中小企业精准拓客引
引言:在数据洪流中,如何精准锁定商机? 在竞争激烈的商业环境中,中小企业如何从海量信息中快速筛选出高价值客户?如何避免无效沟通,精准触达目标企业? 探商宝——一款基于大数据与AI技术的企业信…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
