都是对的
首先内存确实是 zend 一次申请一块大内存,而不是系统调用,因为系统调用代价很高
php 脚本代码释放掉的内存也是给了 zend 内核,而不是还给系统
引用计数释放掉的内存和 php_request_shutdown 释放掉的内存都是还给 zend,zend 不还给系统
fpm 的运行原理是:
a. fpm 是多进程的,是同步 io,也就是 php 脚本代码调用 io 请求会阻塞,例如 http 请求,mysql 请求,文件读写
b. fpm 的每个进程有自己的 zend 内核在运行,每个进程维护自己的内存块
c. fpm 可以设置最大进程数,避免内存使用过高,例如 20 个,不用设置太大,因为 cpu 上下文切换在高并发时返而会消耗大量 cpu,具体根据业务请求阻塞 io 调整
d. fpm 可以设置每个进程可以接受的请求数,超过这个请求数就结束进程重新再起一个,避免内存泄露
根据以上可知,想调整 fpm,需要关注内存和接收并发的能力,文档:
https://www.php.net/manual/zh/install.fpm.configuration.php下面给出例子:
1. 楼主为了避免内存一直占用,需要限制 php 进程数。根据楼主的硬件配置,目前不知道楼主的业务,这里给出假设。
2. 设置 pm 为 dynamic,然后设置 max_children 为 64,这样可以限制 fpm 最大启用 64 个进程。
3. 设置 start_servers 为 16,为 fpm 启动时为 16 个进程,这样 fpm 可同时处理 16 个请求。
4. 设置 min_spare_servers 为 16,这样空闲时最小为 16 个进程,max_spare_servers 为 32,空闲时最大为 32 个进程。至于 fpm 空闲时到底会因为什么原因在这个区间伸缩,等我有时间看了相关内核源码再说。。
5. 设置 max_requests 为 10240,为每个进程处理 10240 个请求进程就结束进程重启起一个新的,避免内存泄露。
注:可以根据 xhprof ( php7 可以使用 Tideways )做分析