PHP卡死通常不是内存不足,而是死循环、阻塞I/O或资源未释放;可通过memory_limit是否触发报错、top看CPU占用、strace跟踪系统调用、/proc/PID/status查真实内存及lsof查文件句柄快速定位。

PHP源码运行卡死,不一定是内存不足;更常见的是死循环、阻塞 I/O、未释放的资源或信号处理异常。
怎么快速判断是不是内存耗尽?
看 memory_limit 是否被触发,而不是凭感觉。PHP 在内存超限时默认报错 Fatal error: Allowed memory size of X bytes exhausted,不会“卡死”——它会直接崩溃并输出错误(除非被 @ 抑制或错误报告关闭)。
- 检查
php.ini中的memory_limit值(如128M),用ini_get('memory_limit')运行时确认 - 开启
display_errors = On和error_reporting = E_ALL,确保错误不被静默吞掉 - 用
memory_get_usage(true)在关键位置打点,观察内存是否阶梯式暴涨而非缓慢爬升 - 如果脚本既不报错也不返回,且
top里php进程 CPU 占用持续 99%,大概率不是内存问题,是逻辑卡在某处
Linux 下实时盯住 PHP 进程的硬件资源
别只看 free -h 或 df -h ——卡死往往发生在单个进程维度,全局资源充足但局部阻塞。
- 用
ps aux --sort=-%cpu | head -20找出 CPU 跑满的 PHP 进程 PID - 对准 PID 执行
strace -p,看它最后卡在哪个系统调用(比如停在-e trace=network,file,process recvfrom就是网络读阻塞,停在futex可能是锁竞争) - 用
cat /proc/查实际物理内存占用和线程数,比/status | grep -E 'VmRSS|Threads' memory_get_usage()更真实 - 注意
lsof -p,若打开文件数接近ulimit -n上限(如 1024),可能因无法新建 socket 或 fopen 而挂起
哪些 PHP 操作容易“假死”却和内存无关?
这类问题常被误判为内存爆炸,实际是同步阻塞或外部依赖失联。
-
file_get_contents('http://slow-api.com'):默认无超时,DNS 解析失败或对方不回包就会卡几十秒 -
mysqli_connect()+mysqli_query():连接池空或 MySQL 死锁时,可能等锁或等连接,mysqli.reconnect=Off下更易僵住 - 递归没设深度限制 + 没写
return,或while (true)缺少break条件,CPU 拉满但内存稳定 - 使用
stream_socket_client()且未设stream_set_timeout(),底层 TCP 握手失败也会无限等待
真正难排查的,是那些既不占 CPU 也不报错、strace 显示停在 epoll_wait 或 poll 的情况——这说明 PHP 正在等某个异步事件,而事件源(比如 Redis 连接、消息队列)已断开但未触发超时,得靠 set_time_limit() 或底层 socket timeout 参数兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











