温馨提示×

ubuntu php-fpm为何占用内存高

小樊
43
2026-09-01 11:24:27
栏目: 编程语言

在 Ubuntu 上 php-fpm 占用内存高 是很常见的问题,通常不是“泄漏”,而是由配置和请求模式决定的。下面按常见原因 → 排查方法 → 解决建议来说明。


一、最常见原因

1. php-fpm 进程数太多(最主要)

php-fpm 是多进程模型,每个 worker 进程都会占用独立内存。

例如:

pm = dynamic
pm.max_children = 100

如果每个进程 30–50MB:

100 × 40MB = 4GB

✅ 这是“内存高”的第一嫌疑


2. pm 模式设置不合理

常见三种模式:

模式 特点 风险
static 固定进程数 内存稳定但容易浪费
dynamic 动态增减 默认最常见
ondemand 按需启动 最省内存(适合低流量)

很多人用 dynamicmax_children 设得很大。


3. PHP 脚本本身吃内存

以下情况会显著增加内存:

  • 一次性读取大文件
  • 大数组 / 大循环
  • 未释放的资源(DB、Redis、curl)
  • Composer 依赖过重
  • 框架(Laravel / Symfony)本身占用大

可检查:

echo memory_get_peak_usage();

4. OPcache 没开或配置不当

没开 OPcache:

  • 每次请求都重新编译 PHP
  • CPU + 内存都高

推荐:

opcache.enable=1
opcache.memory_consumption=128

5. 第三方扩展内存占用大

常见“内存刺客”:

  • xdebug(开发环境才开)
  • ionCube
  • 某些国产加密扩展

6. 系统里有多个 PHP 版本

Ubuntu 上可能同时有:

  • php7.4-fpm
  • php8.1-fpm
  • php8.2-fpm

你以为只跑一个,其实多个都在占用内存。

检查:

ps aux | grep php-fpm

二、如何快速排查

1. 看 php-fpm 占了多少

ps aux --sort=-rss | head

或:

top -p $(pgrep php-fpm | tr '\n' ',' | sed 's/,$//')

2. 看当前进程数

pgrep php-fpm | wc -l

3. 看 php-fpm 状态页(强烈推荐)

在 pool 配置中:

pm.status_path = /status

访问:

http://localhost/status

能看到:

  • active processes
  • idle processes
  • max children reached

三、典型优化方案(立竿见影)

✅ 1. 降低 max_children

计算公式(保守):

max_children ≈ 总内存 / 单进程内存

例如 2GB 内存:

2048 / 40 ≈ 50

✅ 2. 低流量服务器用 ondemand

pm = ondemand
pm.max_children = 20
pm.process_idle_timeout = 10s

✅ 3. 限制请求数(防内存泄漏)

pm.max_requests = 500

让 worker 自动重启,避免长期运行堆积内存。


✅ 4. 关闭不需要的 PHP 模块

php -m

禁用:

  • xdebug(生产)
  • 不用的扩展

✅ 5. 开启 OPcache

opcache.enable=1
opcache.enable_cli=1

四、一个“正常”的参考值

  • 小型站点:php-fpm 占 100–300MB
  • 中型 Laravel: 500MB–1.5GB
  • 超过 2GB 基本都要查配置

五、如果你愿意,我可以进一步帮你

你可以贴出:

  1. php-fpm.conf 或 pool 配置
  2. free -h
  3. ps aux | grep php-fpm
  4. 用的 PHP 版本和框架

我可以直接帮你算该设多少 max_children 最合适

0