首先需要定位内存泄漏的具体原因,可通过以下命令快速排查:
htop命令(按Shift+M按内存排序),定位占用内存较高的php-fpm进程;php-fpm status(或Nginx/Apache的status页面)查看进程的内存使用趋势,判断是否持续增长。通过优化配置限制进程内存使用,避免泄漏累积:
pm.max_requests:该参数控制单个php-fpm进程处理请求数后自动重启(如pm.max_requests = 500),强制释放内存。修改路径为/etc/php-fpm.d/www.conf;pm.max_children:根据服务器内存计算合理值(如可用内存/单个进程内存,假设服务器有8GB内存,单个php-fpm进程占用50MB,则pm.max_children = 160),避免过多进程耗尽内存;pm.start_servers/pm.min_spare_servers/pm.max_spare_servers:根据CPU核心数调整(如pm.start_servers = CPU核心数×4),平衡进程创建与销毁的开销。修复代码中的内存泄漏点,从根源解决问题:
$conn->close())、文件句柄(fclose($file))后,主动关闭资源;static array)、监听器的滥用,防止对象无法被垃圾回收;unset()释放变量:不再需要的变量(如大数组、临时对象)及时用unset()销毁;通过工具精准定位泄漏位置(适用于自定义代码或第三方扩展):
wget http://valgrind.org/downloads/valgrind-3.16.1.tar.bz2 → tar -jxvf valgrind-3.16.1.tar.bz2 → cd valgrind-3.16.1 → ./autogen.sh → ./configure → make → sudo make install;USE_ZEND_ALLOC=0(禁用Zend内存管理器,提升Valgrind检测准确性);valgrind --leak-check=full --log-file=/data/log/valgrind.log /usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf;/data/log/valgrind.log,定位泄漏的具体文件及行号(如==12345== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1)。作为临时解决方案,通过定时任务定期重启php-fpm,释放累积的内存:
/usr/local/script/kill_php_fpm.sh:#!/bin/bash
pids=$(ps -ef | grep php-fpm | grep -v "grep" | awk '{print $2}')
if [ -n "$pids" ]; then
kill -9 $pids
fi
/usr/local/php/sbin/php-fpm --daemonize --fpm-config /usr/local/php/etc/php-fpm.conf
*/5 * * * * /usr/local/script/kill_php_fpm.sh。php.ini,设置opcache.enable=1,减少脚本重复编译的内存消耗;php.ini或pecl命令移除未使用的扩展(如imagick、xdebug),降低内存占用;