PHP扩展-生命周期和内存管理
1. PHP源码结构
PHP的内核子系统有两个,ZE(Zend Engine)和PHP Core.
ZE负责将PHP脚本解析成机器码(也成为token符)后,在进程空间执行这些机器码;ZE还负责内存管理,变量作用域管理和对PHP函数的调度管理。
PHP Core负责和SAPI层的通信;PHP Core也为safe_mode, open_basedir的检查提供了统一控制层;PHP Core还提供了streams层,用于用户域的文件和网络IO操作。其中SAPI(Server Application Programming Interface)通常包含Nginx,Apache,IIS,CLI,CGI等主机环境。
PHP扩展在ZE和PHP Core的基础上提供对各种常用操作的封装,比如对mysql,redis,memcache,sqlite等的读写,对json,xml文件的解析,对soap,sokcet,curl的网络协议的封装,对加密解密压缩解压缩等的封装,对图像处理的封装等等。有些扩展是从零开始实现某个功能,比如按照redis的通信协议使用C来实现和redis的通信;有些扩展则是通过调用系统已有的库,比如图片处理的gb扩展需要系统本身要安装了相应的gd库。
在PHP源码php-5.6.24/ext中提供了78个扩展。
总之,由ZE和PHP Core提供基础的架构,由EXT(扩展)提供用户域的各种操作。
以php-5.6.24源码为例,ZE对应文件夹php-5.6.24/Zend, PHP Core对应文件夹php-5.6.24/main, 扩展对应文件夹php-5.6.24/ext。
2. PHP扩展的生命周期
PHP在接收到SAPI命令时,首先初始化并启动它的内核子系统,在内核子系统的启动快结束时,PHP开始加载它的扩展代码并对扩展初始化,此时PHP将调用每个模块的初始化例程Module Initialization routine (MINIT)。
MINIT(Module Initialization)
PHP调用MINIT相关例程,使得每个扩展有机会初始化内部变量、分配资源、注册资源处理句柄,以及向ZE注册自己的函数,以便于脚本调用这其中的函数时候ZE知道执行哪些代码
RINIT(Request Initialization)
在模块初始化完成后,PHP等待来自SAPI的请求,当接收到SAPI请求后,由ZE为当前被请求的php脚本创建运行环境,并调用每个扩展的Request Initialization(RINIT)函数,使得每个扩展有机会设定特定的环境变量,根据请求分配资源,或者执行其他任务,如审核。
这里所说的SAPI请求分为两类,一类是Apache, IIS, 和其他成熟的web server SAPIs,他们在启动时PHP先执行了MINIT,之后等待来自用户的页面请求,当收到请求后执行RINIT;另一类SAPI请求则是CGI or CLI SAPIs,PHP在收到这类SAPI请求时,执行完MINIT马上就执行RINIT。
当RINIT请求初始化完毕后,ZE接回控制权并将当前被请求的脚本翻译成tokens, 最终构成opcodes(操作码),opcodes被执行过程中,如果某个opcode要求执行某个扩展函数,这是ZE就会将相关参数绑定到改函数,并将控制权临时交给该函数去执行,直到该函数执行完毕。
RSHUTDOWN(Request Shutdown)
PHP脚本运行结束后,PHP调用每个扩展的请求关闭(RSHUTDOWN)函数以执行最后的清理工作(如将session变量存入磁盘)。接下来,ZE执行清理过程(垃圾收集),有效地对之前的请求期间用到的每个变量执行unset()。
MSHUTDOWN(Module Shutdown)
当RSHUTDOWN完成后,PHP继续等待SAPI的其他文档请求或者是关闭信号。对于CGI和CLI等SAPI,没有“下一个请求”,所以SAPI立刻开始关闭。关闭期间,PHP再次遍历每个扩展,调用其模块关闭(MSHUTDOWN)函数,并最终关闭自己的内核子系统。
GINIT
初始化全局变量
GSHUTDOWN
释放全局变量
MINFO
设置phpinfo模块的信息,phpinfo要等级每个扩展的配置信息
// main/php.h
#define PHP_MINIT ZEND_MODULE_STARTUP_N
#define PHP_MSHUTDOWN ZEND_MODULE_SHUTDOWN_N
#define PHP_RINIT ZEND_MODULE_ACTIVATE_N
#define PHP_RSHUTDOWN ZEND_MODULE_DEACTIVATE_N
#define PHP_MINFO ZEND_MODULE_INFO_N
#define PHP_GINIT ZEND_GINIT
#define PHP_GSHUTDOWN ZEND_GSHUTDOWN #define PHP_MINIT_FUNCTION ZEND_MODULE_STARTUP_D
#define PHP_MSHUTDOWN_FUNCTION ZEND_MODULE_SHUTDOWN_D
#define PHP_RINIT_FUNCTION ZEND_MODULE_ACTIVATE_D
#define PHP_RSHUTDOWN_FUNCTION ZEND_MODULE_DEACTIVATE_D
#define PHP_MINFO_FUNCTION ZEND_MODULE_INFO_D
#define PHP_GINIT_FUNCTION ZEND_GINIT_FUNCTION
#define PHP_GSHUTDOWN_FUNCTION ZEND_GSHUTDOWN_FUNCTION
3. PHP扩展的内存管理
ZE在执行自己内部的内存管理时,通过附加的标志来标识某某内存变量是否是持久性的,对于非持久内存,ZE会去清理。但在扩展内部最好还是自己去清理非持久内存,因为扩展自己请求分配的非持久内存,将在长时间内保持为未回收状态,这样与之相关的资源长时间得不到释放。
参考文章:Extension Writing Part I: Introduction to PHP and Zend

PHP扩展-生命周期和内存管理的更多相关文章
- JVM的内存管理、对象的生命周期、内存泄漏
1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...
- Activity 生命周期及其栈管理方式
Activity 生命周期 Android 系统用栈的形式管理 Activity , 当新的 Activity 被创建是, 会被放置到栈顶, 这个 Activity 会进入到运行状态, 而前一个 Ac ...
- WebApp中的页面生命周期及路由管理
最近切换到一个新项目,使用的技术栈是Require+Backbone,鉴于对鞋厂webapp框架的了解,发现这个新项目有些缺陷,主要是单纯依赖Backbone造成的,也就是Backbone的好和坏都在 ...
- garbage collection - 垃圾收集 生命周期 跟踪内存使用
Professional.JavaScript.for.Web.Developers.3rd.Edition.Jan.2012 JavaScript is a garbage-collected la ...
- React源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...
- React 源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...
- Elasticsearch7.X ILM索引生命周期管理(冷热分离)
Elasticsearch7.X ILM索引生命周期管理(冷热分离) 一.“索引生命周期管理”概述 Elasticsearch索引生命周期管理指:Elasticsearch从设置.创建.打开.关闭.删 ...
- Elasticsearch索引生命周期管理方案
一.前言 在 Elasticsearch 的日常中,有很多如存储 系统日志.行为数据等方面的应用场景,这些场景的特点是数据量非常大,并且随着时间的增长 索引 的数量也会持续增长,然而这些场景基本上只有 ...
- Elasticsearch索引生命周期管理探索
文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484130&idx=1&sn=454f199 ...
随机推荐
- “.Net 社区虚拟大会”(dotnetConf) 2016 Day 3 Keynote: Scott Hanselman
美国时间 6月7日--9日,为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开,美国时间6.9 是第三天, Scott Hanselman 做Keynote.今天主题围绕的是.NET ...
- Jquery 搭配 css 使用,简单有效
前几篇博客中讲了Jquery的基础和点击实际,下面来说一下和css搭配着来怎么做 还是和往常一样,举个例子 好几个方块,然后设置颜色 <!DOCTYPE html PUBLIC "-/ ...
- html与html5
HTML 是一种在 Web 上使用的通用标记语言.HTML 允许你格式化文本,添加图片,创建链接.输入表单.框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示.HTML 的关键是标签,其作用是 ...
- ASP.NET Core的路由[5]:内联路由约束的检验
当某个请求能够被成功路由的前提是它满足某个Route对象设置的路由规则,具体来说,当前请求的URL不仅需要满足路由模板体现的路径模式,请求还需要满足Route对象的所有约束.路由系统采用IRouteC ...
- 【开发软件】 在Mac下配置php开发环境:Apache+php+MySql
本文地址 原文地址 本文提纲: 1. 启动Apache 2. 运行PHP 3. 配置Mysql 4. 使用PHPMyAdmin 5. 附录 有问题请先 看最后的附录 摘要: 系统OS X ...
- 【工具使用】mac电脑使用技巧
本文地址 分享提纲: 1. mac命令行和finder的交互 2. 一些mac的插件 3. 一些开发的配置 1.mac命令行和findder交互 1)命令行中打开当前文件夹: o ...
- TYPESDK手游聚合SDK服务端设计思路与架构之一:应用场景分析
TYPESDK 服务端设计思路与架构之一:应用场景分析 作为一个渠道SDK统一接入框架,TYPESDK从一开始,所面对的需求场景就是多款游戏,通过一个统一的SDK服务端,能够同时接入几十个甚至几百个各 ...
- Java之多态(二)
package test05;import test06.Car1;public class DuoTai_Test02 { /**多个对象,一个形态 * Tiger.Lion.Snake → Ani ...
- eclipse — 导入android项目后识别成java项目的问题及解决
最近在eclipse导入android项目的时候遇到了奇葩问题,再此记录 遇到的问题就是:将完好的android项目导入到eclipse的时候,原本这是一个很容易的事情,但是导入成功后发现,,,靠ec ...
- Android Studio分类整理res/Layout中的布局文件(创建子目录)
res/layout中的布局文件太杂,没有层次感,受不了的我治好想办法解决这个问题. 前几天看博客说可以使用插件分组,可惜我没找到.知道看到另一篇博客时,才知道这个方法不能用了. 不能用插件,那就手动 ...