Nginx底层设计与源码分析
上QQ阅读APP看书,第一时间看更新

3.1 Nginx内存管理简介

应用程序的内存总体上可以分为栈内存、堆内存等。对于栈内存而言,其在函数调用以及函数返回时可以实现内存的自动管理(编译器会自动生成相关代码)。因此,我们通常所说的应用程序内存管理是指堆内存管理。程序员使用堆内存的步骤可以简化为3步:申请内存、使用内存和释放内存。

1)申请内存通常需要程序员在代码中显式声明,比如C语言中malloc函数的调用、C++语言中new的使用、Java中new的使用等。

2)内存的使用是由程序逻辑决定的。通常,申请后的内存只在单线程中使用,如果该内存需要在多线程中使用,需要考虑多线程安全的问题。

3)释放内存对于单线程比较简单,但是对于多线程会烦琐得多,因为需要知道在哪个时刻才能释放内存。很多高级语言提供了垃圾回收机制,如Java、Go,但是对于没有垃圾回收机制的C语言、C++语言而言,内存回收则会复杂得多。

Nginx采用多进程单线程模型,主进程(Master进程)负责监控工作进程,工作进程(Worker进程)负责监听客户端的请求,处理客户端的请求并返回结果。每个工作进程只有一个线程。由于工作进程之间需要通信,Nginx采用共享内存方案,比如记录总的请求数。通过共享内存,每个工作线程在处理请求时都会更新位于共享内存中用于记录总请求数的变量。可以看出,对于Nginx而言,不仅每个进程自身需要内存管理,进程之间共享的内存也需要内存管理。综上所述,Nginx需要管理两种内存:进程内内存;进程间共享内存。

前面讲到,堆内存的使用分为3步:申请内存、使用内存、释放内存。站在内存管理员的角度看,当应用程序申请内存时,我们需要快速找到符合要求的内存块。当应用程序释放内存时,我们需要快速回收内存,减少内存碎片。这两个问题是我们真正需要关心的。下面先介绍本章后续章节的安排:3.2节介绍Nginx进程内内存管理方案;3.3节讲解Nginx共享内存管理方案。Nginx内存管理相关代码读者可以参考src/core/ngx_palloc.h、src/core/ngx_palloc.c文件。