nginx高效内存池分析

2023-05-16

背景分析

      nginx作为一个高效的服务器服务器框架,在网站搭建领域占领了很大比例;以成为不可忽视的一大块领域;它能如此高效的运行跟他的优秀的内存管理机制有很大的关系,今天抽出时间就来学习和分析下它优秀的内存管理机制。

 

代码分析

      首先我们来看下nginx的内存池的初始化部分;




ngx_pool_t *
ngx_create_pool(size_t size)
{
    ngx_pool_t  *p;

    p = ngx_memalign(NGX_POOL_ALIGNMENT, size);
    if (p == NULL) {
        return NULL;
    }

    p->d.last = (u_char *) p + sizeof(ngx_pool_t);
    p->d.end = (u_char *) p + size;
    p->d.next = NULL;
    p->d.failed = 0;

    size = size - sizeof(ngx_pool_t);
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;

    p->current = p;
    //p->chain = NULL;
    p->large = NULL;
    //p->cleanup = NULL;
    //p->log = log;

    return p;
}

这是内存池初始化的部分,可以看到首先开辟了一块内存p->d.last 这个是内存池中可用内存的初始地址的地方,其中ngx_pool_t这个结构体是内存池里面的描述,内存池占用,不可以使用;这样就不难理解 p->d.last = (u_char*)p + sizeof(ngx_pool_t);这段代码了;再看下面p->d.end 指向的是内存池的结束的地方;p->d.next 这个变量是指向下一个内存块的,因为这个内存块没有使用,所以下一个内存块还没有开辟,自然为空;再看p->max 这个变量是描述这个内存块的可用内存大小;NGX_MAX_ALLOC_FROM_POOL这个弘一般是定义一个页的大小;

p->current 这里是指向当前使用的内存块的;p->large 这的变量是为了指向大内存管理这个地方的;

其中注释的地方现在不做了解,如果有兴趣自行百度;好了,到这里基本山nginx的内存池的初始化算是搞清楚了;下面看下内存的分配部分;

 

内存分配

      先上代码:

void *ngx_palloc(ngx_pool_t *pool, size_t size)
{
#if !(NGX_DEBUG_PALLOC)
	if (size <= pool->max) {
		return ngx_palloc_small(pool, size, 1);
	}
#endif

	return ngx_palloc_large(pool, size);
}

可以看到在分配内存的时候首先判断,需要分配内存的大小是否大于内存块的总大小,如多小于在内存池中分配,如果大于,则分配在大内存管理这边;

下面看看小内存的分配

static inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
{
	u_char		*m;
	ngx_pool_t	*p;

	p = pool->current;

	do 
	{
		m = p->d.last;
		if (align)
		{
			m = ngx_align_ptr(m, NGX_ALIGNMENT);
		}

		if ((size_t)(p->d.end-m)>=size)
		{
			p->d.last = m + size;
			return m;
		}
	} while (p);

	return ngx_palloc_block(pool, size);
}

在这里可以看出总的逻辑就是判断当前内存块是否足够分配这块内存,如果足够则分配,如果不够则开辟一块新的内存块然后分配;

大内存快的分配不做详解;后面会附上代码,如果有不理解的欢迎联系本人交流;留下本人QQ:820121952

 

好了,在这里大概的逻辑了解了,现在我们了解下内存池回收的处理

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) {
			fprintf(stderr, "free: %p", l->alloc);
		}

		for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
			fprintf(stderr, "free: %p, unused: %zu", p, p->d.end - p->d.last);

			if (n == NULL) {
				break;
			}
		}
}

#endif
	for (l = pool->large;l; l=l->next)
	{
		if (l->alloc)
		{
			ngx_free(l->alloc);
		}
	}

	for (p=pool,n=pool->d.next;;p=n,n=n->d.next)
	{
		ngx_free(p);

		if (n==NULL)
		{
			break;
		}
	}


}

额循环遍历释放了整个内存池;

总结:由此可见,此内存池的内存管理在分配不固定大小的内存使用的时候是非常高效的,然而如果在长时间内内存池得不到释放 的话将会吃尽内存;因此这个内存管理方式适合在一段时间就会清理一次内存的情况;不适用于长时间内存池得不到释放的情况。

附上代码:链接:https://pan.baidu.com/s/1MCUAnQcxDRTu9NVviFjShA 密码:npft

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nginx高效内存池分析 的相关文章

  • 禁用 Kubernetes NGINX 入口的 SSL 重定向

    默认情况下 在 Kubernetes NGINX 入口中启用 SSL 重定向 如何禁用此功能 目前的实施如下 apiVersion extensions v1beta1 kind Ingress metadata name project
  • NGINX 和 Spark Java 之间的跨源通信

    我正在将 NGINX 和 Sparkjava 用于我的 Web 应用程序 我确信我已正确启用所有 CORS 标头 尽管如此 我还是得到了 XMLHttpRequest 无法加载http localhost 3003 platformAPI
  • Nginx 作为负载均衡器,具有 75% 和 25% 加权路由

    我是 Nginx 新手 我有两台服务器 serverA 和 serverB 我希望 75 的请求发送到 serverA 其余 25 的请求发送到 serverB 这可能吗 使用nginx加权路由 stream upstream stream
  • nginx - 使用 ssl 支持设置多个 server_name

    我很想使用 nginx 来为具有多个域名和 SSL 的网站提供服务 webmail example com webmail beispiel de 两者都使用相同的虚拟主机 因此我只设置 server name 两次 问题是 我需要 ngi
  • 将 docker-compose.yml 中的包安装到 docker 容器中

    我是 docker 和 docker compose 的初学者 我需要你的帮助 我正在使用 docker compose 制作 PHP NGINX PostgresQL symfony 开发环境 这里是 web image nginx 1
  • 如何在 nginx 反向代理后面安全地检测 CakePHP 中的 SSL?

    CakePHP 我见过的所有版本 检查 SERVER HTTPS 查看请求是否是通过 HTTPS 而不是普通 HTTP 发出的 我使用 nginx 作为负载均衡器 后面是 Apache 应用程序服务器 由于 SSL 连接在负载均衡器处终止
  • 致命错误:未捕获错误:调用未定义的函数 bcadd()

    安装 eduTrac SIS 并访问 仪表板 后出现此错误 Ubuntu 16 4 PHP 7 0 php7 0 fpm Apache2 Nginx URL 给出错误 500 并显示 nginx error log FastCGI 在 st
  • 在龙卷风 v4+ 下,WebSocket 连接被拒绝并显示 403

    我有一个旧的龙卷风服务器 可以处理普通的 WebSocket 连接 我通过 Nginx 将这些连接从 wss info mydomain com 代理到 wss mydomain com 8080 以便绕过阻止非标准端口的客户代理 最近升级
  • nginx/uwsgi 服务器的持久内存中 Python 对象

    我怀疑这是否可能 但这是问题和提出的解决方案 提出的解决方案的可行性是这个问题的对象 我有一些需要可用于所有请求的 全局数据 我将这些数据保存到 Riak 并使用 Redis 作为缓存层以提高访问速度 目前 数据被分为约 30 个逻辑块 每
  • 设置 nginx 具有多个 IP

    我的 nginx 配置文件位于 etc nginx sites available 下 有两个上游说 upstream test1 server 1 1 1 1 50 server 1 1 1 2 50 upstream test2 ser
  • 生产中的静态文件出现 Django 301 和 403 禁止错误

    我正在尝试使用 nginx 和 Gunicorn 在 ubuntu 14 04 vps 上部署 django 网站 但是我的 css 文件和 js 文件没有加载 我在默认的 django 开发服务器上开发了它 它运行得很好 但是当我部署我的
  • nginx 的“ssl”指令已弃用,请使用“listen ... ssl”

    NGINX 升级后v1 15 2开始收到警告 nginx warn the ssl directive is deprecated use the listen ssl directive instead in usr local etc
  • Dokku:从应用程序监听多个端口

    我正在使用 dokku 部署一个节点应用程序 带有express js 我的应用程序由 2 个 Express js 应用程序组成 它们监听两个不同的端口 一个是主应用程序 另一个是网络界面kue 一个简单的 Node js 作业队列 当我
  • 部署解耦的前端+后端应用程序

    我使用两个完全解耦的组件编写了一个网络应用程序 一个基于 Place Framework 并服务以下请求的 API 类型 api 任何客户 基于解耦的前端AngularJS建造使用grunt build 现在 前端与API但我希望这两个单元
  • 由于 try_files $uri 别名错误,Nginx 别名中断

    我有一个版本化的 Symfony API 实例 我想按以下方式配置它 api com api v1 gt srv api v1 public index php api com api v2 gt srv api v2 public ind
  • nginx 502 错误网关

    当使用 Spawn fcgi 生成 php5 cgi 时 我收到 502 Bad Gateway with nginx 我使用它来跨越服务器启动上的实例 并在 rc local 中使用以下行 usr bin spawn fcgi a 127
  • 通过 ESI:include 设置 Cookie,如何?

    我正在尝试使用 esi 在我的网站上创建忍者缓存 这个想法是 该网站大部分是静态的 我只需要在用户是否登录时做一些花哨的事情 所以我试图在页面A上放置一个 并在页面B的应用程序中设置触发器 这样我就可以将页面 A 缓存在 varnish 上
  • Nginx 配置文件在 Elastic Beanstalk 部署期间被覆盖?

    我需要将 p3p 标头添加到标准 Nodejs 和 Nginx Elastic Beanstalk 上的静态资源位置 我创建了一个ebextension脚本如上所解释这个问题 https stackoverflow com question
  • Access-Control-Allow-Origin值跨站缓存

    我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点 只要客户端从不访问这两个站点 它似乎就可以工作 但如果它们这样做 就会出现缓存 跨站点问题 Allow cross origin location eot
  • Kubernetes - 一个 Ingress 中的多个配置

    我在同一个 Kubernetes 集群中运行不同的应用程序 我希望多个域能够访问我的 Kubernetes 集群 并根据域进行重定向 对于每个域 我想要不同的注释 配置 如果没有注释 我的入口部署如下 apiVersion networki

随机推荐

  • WebView显示图片适配屏幕宽度

    情景一 WebView加载url 图片直接就是标签出来的 xff0c 还是一张巨大的图片 xff0c 直接导致webview加载只有截取了屏幕大小的宽度 xff0c 看不到整张图片 xff0c 测试要求适配屏幕宽度 于是有了这篇博客记录一下
  • 最全Pycharm教程(6)——将Pycharm作为Vim编辑器使用

    如果觉得这篇文章对您有所启发 xff0c 欢迎关注我的公众号 xff0c 我会尽可能积极和大家交流 xff0c 谢谢 最全Pycharm教程 xff08 1 xff09 定制外观 最全Pycharm教程 xff08 2 xff09 代码风格
  • C++ String拼接

    做个笔记 看下边的代码 xff1a span class hljs keyword string span str1 61 span class hljs string 34 ls 34 span span class hljs comme
  • xxl-job源码之执行器执行任务的核心流程

    xxl job源码之执行器执行任务的核心流程 先来一张图大致看看 如果看的不清晰 xff0c 可以前往地址 xff1a https www processon com view link 604e0b860791291f25613424 密
  • Choreographer 丢帧计算

    在Logcat中 xff0c 我们经常会看到系统输出如下Log xff1a Choreographer Skipped 180 frames The application may be doing too much work on its
  • JWT的数字签名的简单理解

    一 JWT概念 json web token 二 JWT与原始token的区别 JWT是对原始security的oauth2 token的增强 原始的token只是一个uuid xff0c 没有任何意义 JWT包含了部分业务信息 xff0c
  • Docker容器内部无法访问外网原因之一

    问题描述 部署了一个Docker环境 xff0c 宿主机可以访问Internet xff0c 启动了一个容器发现容器里的服务无法访问Internet xff0c Docker网络使用的是桥接 xff08 bridge xff09 模式 问题
  • nohup: failed to run command `java': No such file or directory解决

    程序里远程执行shell命令 xff08 nohup java jar xff09 的执行 xff0c 后台日志报错如下 xff1a nohup failed to run command 96 java 39 No such file o
  • C++中,两个头文件互相引用(转载)

    定义了两个头文件 a h include 34 b h 34 class a b b1 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 b
  • CEF加载本地H5页面,支持JS和C++交互

    今天闲来无事 xff0c 写个CEF相关的博客 xff0c 很多同学还只会加载简单的CEF控件 xff0c 但是涉及到需要和H5页面交互就比较头疼了 xff0c 今天来简单介绍一下 xff0c 有兴趣可以加qq 295282563 xff0
  • Linux下编译tinyhttpd

    Linux下编译tinyhttpd 来源 xff1a https blog csdn net qq673675158 article details 104927245 spm 61 1001 2014 3001 5506 根据说明 xff
  • 语音编码技术,AMR、AMR-NB、AMR-WB、EVS总结

    最近对实时语音编码技术有点兴趣 xff0c 于是了解了一下 一开始听说AMR NB窄带编码 xff0c 搜索才发现更多的编码技术 xff0c 这里总结一下 xff0c 便于日后查看 一 什么是AMR AMR WB 全称Adaptive Mu
  • xxl-job源码之admin调度中心的线程们

    xxl job中的线程们 启动后 xff0c 从控制台看看admin调度中心 span class token string 34 xxl job admin JobFailMonitorHelper 34 span 64 span cla
  • imx6ull移植OpenWRT系统

    参考 xff1a i mx6ul开发板移植openwrt系统 https blog csdn net qq 40614144 article details 105538483 有几点需要补充 xff1a 1 在imx6ull的Linux内
  • 最近的学习目标

    自己动手编写TCP IP协议栈 xff0c 或者简单点的UDP协议栈 xff0c 参考LWIP协议栈 xff1b 自己动手实现一个HTTP服务器 xff0c 参考tinyhttpd xff0c lighttpd xff0c uhttpd x
  • make[1]: *** 没有规则可以创建“all”需要的目标“hello_world.srec”。 停止。

    在uboot1 1 4目录下 make后 xff0c 出现错误 xff1a make 1 没有规则可以创建 all 需要的目标 hello world srec 停止 发现以下方法可以解决 xff1a 今天在新安装的Debian etch中
  • could not resolve host: github.com 问题解决办法

    点击这里 xff0c 查看相关内容 xff1a https blog csdn net zhenfengshisan article details 57566709
  • 解决无法Ping通Github

    解决无法Ping通Github https blog csdn net u012552275 article details 61654857 Ubuntu平台同理 xff1a gedit etc hosts 在最后添加 192 30 25
  • STM32 ST-LINK Utility介绍、下载、安装、使用方法

    STM32 ST LINK Utility介绍 下载 安装 使用方法 原文如下 xff1a https blog csdn net ybhuangfugui article details 52597133
  • nginx高效内存池分析

    背景分析 nginx作为一个高效的服务器服务器框架 xff0c 在网站搭建领域占领了很大比例 xff1b 以成为不可忽视的一大块领域 xff1b 它能如此高效的运行跟他的优秀的内存管理机制有很大的关系 xff0c 今天抽出时间就来学习和分析