nginx+php-fpm模式php内存泄漏探究

昨天遇到过一次服务器内存告警,查看后发现有个php-fpm进程占用了2G的内存。但我明明在php.ini文件里面,有配置 memory_limit = 256M,那为何会有占用2G内存的php-fpm进程呢?php

这里先简单说一下nginx+php-fpm模式的工做原理。nginx

a.png服务器

  1. nginx服务器fork出n个子进程(worker),php-fpm管理器fork出n个子进程。
  2. 当有用户请求,nginx的一个worker接收请求,并将请求抛到socket中。
  3. php-fpm空闲的子进程监听到socket中有请求,接收并处理请求。

这里要重点说一下第三步骤。第三步涉及到php-fpm进程生命周期的东西。一个php-fpm的生命周期大体是这样的:模块初始化(MINIT)-> 模块激活(RINIT)-> 请求处理 -> 模块停用(RSHUTDOWN) -> 模块激活(RINIT)-> 请求处理 -> 模块停用(RSHUTDOWN)……. 模块激活(RINIT)-> 请求处理 -> 模块停用(RSHUTDOWN)-> 模块关闭(MSHUTDOWN)。在一个php-fpm进程的生命周期里,会有屡次的模块激活(RINIT)-> 请求处理 -> 模块停用(RSHUTDOWN)的过程。这个“请求处理”的大体过程是这样的:php读取相应的php文件,对其进行词法分析,生成opcode,zend虚拟机执行opcode。socket

回到一开始说的PHP配置文件里面的memory_limit 这个东西,其实,它限制的只是这个“请求处理”的内存。因此,这个参数跟php-fpm进程占用的内存并无什么关系。那为何会有占用2G大小的php-fpm进程呢?缘由是这样的:php是用c写的,因此,不免又会一些内存泄露。也就是说,在“请求处理”这个过程结束后,有些变量没有被销毁,而后就致使一个php-fpm进程占用的内存愈来愈大。php-fpm

那么,有什么办法能阻止这个问题呢?方法一:写不泄漏内存的php程序;方法二:在php-fpm配置文件中,将pm.max_requests这个参数设置小一点。这个参数的含义是:一个php-fpm子进程最多处理pm.max_requests个用户请求后,就会被销毁。当一个php-fpm进程被销毁后,它所占用的全部内存都会被回收。code


 

文/_叶左左(简书做者)
原文连接:http://www.jianshu.com/p/9450ab506446
著做权归做者全部,转载请联系做者得到受权,并标注“简书做者”。生命周期

相关文章
相关标签/搜索