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高效内存池分析 的相关文章

随机推荐

  • 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 今天抽出时间就来学习和分析