0

0

PHP内存溢出、命令行和Web服务两种执行方式的理解

不言

不言

发布时间:2018-05-31 16:53:25

|

2272人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了关于PHP内存溢出、命令行和Web服务两种执行方式的理解,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

开发过程中,某个接口由于从数据库读取数据量过大,返回状态为 200,但无响应数据,php错误日志里有如下信息:php fatal error:  allowed memory size of 134217728 bytes exhausted。

很显然这是内存溢出(Out Of Memory)引发的错误,但是令我疑惑的是,Yii 框架的业务日志(application.log)里没有任何输出,页面上也没有 Stack Trace 的错误信息,于是对这个原因进行追查。

原因如下,先看 Yii 框架 CApplication.php 文件核心代码:

public function run()
{    if($this->hasEventHandler('onBeginRequest'))        
$this->onBeginRequest(new CEvent($this));
    register_shutdown_function(array($this,'end'),0,false);    
    $this->processRequest();    
    if($this->hasEventHandler('onEndRequest'))        
    $this->onEndRequest(new CEvent($this));
}

在处理请求前使用了 register_shutdown_function 注册异常终止时的回调,正常来说,PHP 出现异常脚本终止时会回调 end() 方法,在 onEndRequest 事件的监听器中可以使用 error_get_last() 获取到本次错误。

但是,当 OOM 发生时,Linux Out Of Memory killer 会执行 kill -9 发送 SIGKILL 信号,根据 PHP 手册中的说明, SIGKILL 信号无法捕获和拦截,PHP 脚本会直接退出,任何清理代码都不会执行,所以 register_shutdown_function 方法不会发挥作用,自然也不会有后续的日志记录、错误页面显示等流程。

立即学习PHP免费学习笔记(深入)”;

另外在开发中注意到一个现象:通过 Web 访问会出现 OOM,但通过 Console 执行就不会报错。

由此可见两种方式是有区别的,Web 访问时,PHP 脚本进程由 PHP-FPM启动,还要受 FPM 配置文件限制,/etc/php-fpm.d里配置文件有 php_admin_value[memory_limit] = 128M 限制。所以通过 Web 访问时,仅增加 php.ini 中的 memory_limit 无效。

而 Console 方式执行不经过 PHP-FPM,所以仅受 php.ini 中配置的内存参数限制,而开发机中配置的 memory_limit => 512M => 512M,所以此时不会产生 OOM。

这里有个疑问,从实现原理的角度,PHP-FPM 是如何对 PHP 进程管理的?PHP-FPM 真的会用 kill -9 杀死 PHP 脚本进程么?


附上 WebServer、PHP-FPM、PHP 脚本的调用关系:

讯飞智作-讯飞配音
讯飞智作-讯飞配音

讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。

下载

请求首先进入 Web 服务器(如 Nginx),Nginx 分发请求(依据server节点、location节点等配置):

  1. 请求静态资源不需要 FastCGI 处理,直接转到相应文件位置

  2. 动态请求需要 PHP 代码处理,则需要把请求交给实现了 FastCGI 协议的程序(PHP-FPM)

可以在Nginx看到这样的配置信息:“fastcgi_pass 127.0.0.1:9000;”,执行命令“lsof -i:9000”可以看到9000端口刚好是PHP-FPM进程。

Nginx 将请求信息传给了 PHP-FPM,PHP-FPM 分配一个 Worker 进程处理,Worker 进程注册变量 $_GET/$_POST 等,根据请求信息访问指定的 PHP 脚本文件,然后使用 PHP 解释器执行。
(我的理解是:相当于 PHP-FPM 启动了 PHP 解释器,有点像执行了 php -f script.php 命令)

网络请求的信息层层传递,最终到达 PHP,所以在 PHP 代码里可以获取到本次 HTTP 请求的各种参数。

执行哪个 PHP 脚本由 Nginx 告诉 PHP-FPM,在 Nginx 配置中可见一行:

fastcgi_param SCRIPT_FILENAME /home/dev_user/www/xxx/webroot/index.php;

若不指定 PHP 文件,就会使用该默认配置,尝试使用根目录下的 index.php 文件。index.php 里会启动框架程序,由框架找到对应的 Controller 和 Action,完成实际业务逻辑。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号