您的位置:首页 > 运维架构 > Nginx

nginx 内存池分析

2013-11-11 21:11 267 查看
最近nginx的源码刚好研究到内存池,这儿就看下nginx内存池的相关的东西。

一,为什么要使用内存池

  大多数的解释不外乎提升程序的处理性能及减小内存中的碎片,对于性能优化这点主要体现在:
  (1)系统的malloc/free等内存申请函数涉及到较多的处理,如申请时合适空间的查找,释放时的空间合并。
  (2)默认的内存管理函数还会考虑多线程的应用,加锁操作会增加开销。
  (3)每次申请内存的系统态与用户态的切换也及为的消耗性能。
  对于由于应用的频繁的在堆上分配及释放空间所带来的内存碎片化,其实主流的思想是认为存在的,不过也有人认为
这种考虑其实是多余的,在“内存池到底为我们解决了什么问题”一文中则认为,大量的内存申请与释放仅会造成短暂
的内存碎片化的产生,并不会引起大量内存的长久碎片化,从而导致最后申请大内存时的完全不可用性。文中认为对于
确定的应用均是“有限对象需求”,即在任一程序中申请与释放的对象种类总是有限的,大小也总是有一定重复性的,
这样在碎片产生一段时间后,会因为同样的对象申请而消除内存的临时碎片化。

  不过,综上,内存池有利于提升程序在申请及释放内存时的处理性能这点是确定的。内存池的主要优点有:
  (1)特殊情况的频繁的较小的内存空间的释放与申请不需要考虑复杂的分配释放方法,有较高的性能。
  (2)初始申请时通常申请一块较大的连续空间的内存区域,因此进行管理及内存地址对齐时处理非常方便。
  (3)小块内存的申请通常不用考虑实际的释放操作。

二,内存池的原理及实现方法

内存池的原理基本是内存的提前申请,重复利用。其中主要需要关注的是内存池的初始化,内存分配及内存释放。
内存池的实现方法主要分两种:
一种是固定式,即提前申请的内存空间大小固定,空间划分成固定大小的内存单元以供使用如下图示:

[root@localhost pool]# ./pool_t
+++++++++++CREATE NEW POOL++++++++++++
------------------------------
pool begin at: 0x8f33020
->d         :0x8f33020
last = 0x8f33048
end  = 0x8f343a8
next = 0x0
failed = 0
->max       :4960
->current   :0x8f33020
->chain     :0x0
->large     :0x0
->cleanup   :0x0
->log       :0x0

+++++++++++ALLOC 2500+++++++++++++++++
------------------------------
pool begin at: 0x8f33020
->d         :0x8f33020
last = 0x8f33a0c
end  = 0x8f343a8
next = 0x0
failed = 0
->max       :4960
->current   :0x8f33020
->chain     :0x0
->large     :0x0
->cleanup   :0x0
->log       :0x0

+++++++++++ALLOC 2500+++++++++++++++++
------------------------------
pool begin at: 0x8f33020
->d         :0x8f33020
last = 0x8f33a0c
end  = 0x8f343a8
next = 0x8f343c0
failed = 0
->d         :0x8f343c0
last = 0x8f34d94
end  = 0x8f35748
next = 0x0
failed = 0
->max       :4960
->current   :0x8f33020
->chain     :0x0
->large     :0x0
->cleanup   :0x0
->log       :0x0

+++++++++++ALLOC LARGE 5000+++++++++++
------------------------------
pool begin at: 0x8f33020
->d         :0x8f33020
last = 0x8f33a14
end  = 0x8f343a8
next = 0x8f343c0
failed = 0
->d         :0x8f343c0
last = 0x8f34d94
end  = 0x8f35748
next = 0x0
failed = 0
->max       :4960
->current   :0x8f33020
->chain     :0x0
->large     :0x8f33a0c
next = 0x0
alloc = 0x8f35750
->cleanup   :0x0
->log       :0x0

+++++++++++ALLOC LARGE 5000+++++++++++
------------------------------
pool begin at: 0x8f33020
->d         :0x8f33020
last = 0x8f33a1c
end  = 0x8f343a8
next = 0x8f343c0
failed = 0
->d         :0x8f343c0
last = 0x8f34d94
end  = 0x8f35748
next = 0x0
failed = 0
->max       :4960
->current   :0x8f33020
->chain     :0x0
->large     :0x8f33a14
next = 0x8f33a0c
alloc = 0x8f36ae0
->large     :0x8f33a0c
next = 0x0
alloc = 0x8f35750
->cleanup   :0x0
->log       :0x0


View Code

总结:从上面的例子初步能看出一些nginx pool使用的轮廓,不过这儿没有涉及到failed的处理。

五,内存池的释放

这部分在nginx中主要是利用其自己web server的特性来完成的;web server总是不停的接受连接及
请求,nginx中有不同等级的内存池,有进程级的,连接级的及请求级的,这样内存总会在对应的进程,
连接,或者请求终止时进行内存池的销毁。

转载请注明出处:/article/7100230.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: