昨天遇到過一次服務器內存告警,查看後發現有個php-fpm進程佔用了2G的內存。但我明明在php.ini文件裏面,有配置 memory_limit = 256M,那爲何會有佔用2G內存的php-fpm進程呢?php
這裏先簡單說一下nginx+php-fpm模式的工做原理。nginx
a.png服務器
這裏要重點說一下第三步驟。第三步涉及到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
著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。生命週期