一.PHP预处理内存
把内存分为三个层次(small30种规格,large,huge)根据需要的大小各取所需,如果内存仓库里面没有可用内存,则去申请内存
总结:
1.任何内存分配器都需要额外的数据结构来记录内存的分配情况;
2.内存池是代替直接调用malloc/free、new/delete进行内存管理的常用方法;内存池中空闲内存块组织为链表结构,申请内存只需要查找空闲链表即可,释放内存需要将内存块重新插入空闲链表;
3.PHP采用预分配内存策略,提前向操作系统分配2M字节大小内存,称为chunk;同时将内存分配请求根据字节大小分为small、huge、large三种;
4.small内存,采用“分离存储”思想,即将空闲内存块按照字节大小组织为多个空闲链表;
5.large内存每次会分配连续若干个页,采用最佳适配算法;
6.huge内存直接使用mmap函数向操作系统申请内存(申请大小是2M字节整数倍);
7.chunk中的每个页只会被切割为相同规格的内存块;所以不需要再每个内存块添加头部,只需要记录每个页的属性即可;
8.如何方便根据地址计算当前内存块属于chunk中的哪一个页?PHP分配的chunk都是2M字节对齐的,任意地址的低21位即是相对chunk首地址,除以页大小则可获得页号;
内存释放
变量存在zval中 每个变量存储的结构中包含refcount 当变量被使用这个数加一,当着个数为0的时候就被视为垃圾回收了
二.生理周期
一共经过五个阶段
①模块初始化:初始化模块加载扩展,调用模块初始化是每个扩展初始化内部变量,分配资源,注册资源管理器以及向zend注册自己的函数,这样调用其中的函数zend就知道执行这些代码了
②请求初始化:记录请求开始和结束时间,初始化脚本执行所需的执行环境
③脚本执行阶段:执行php代码阶段
④请求关闭阶段:把相应的信息写入到日志文件中或者把session变量存入磁盘等;执行垃圾回收
⑤模块关闭阶段:关闭每个每个模块并关闭自己内核系统
三.PHP运行模式主要以下四种
①cgi 通用网关模式
④fascig常驻行cgi
③cli命令行运行模式
④web模块模式 如Apache的mod_php5.so模块
cgi
cgi公共网关接口,他是web服务器与外部应用程序(cgi程序)之间传递信息的接口标准
web服务器会根据请求的内容,fork一个子进程启动cgi程序,这里就是指PHP的解析器,PHP解析器程序启动后,它就会解析php.ini文件,初始化执行环境,然后解析动态脚本,再把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。当下次再有php任务请求时,在重复之前操作
优点:把webserver和具体的程序处理分开,结构清晰
缺点:每次处理请求都会重启cgi程序(PHP解析器),cgi程序需要解析php.ini等初始化工作,造成效率低下,服务器负担加重
fastcgi
fastcgi就像是一个常驻型的cgi程序,他可以一直运行着。其主要的行为是将cig解释器进程保持在内存中并因此获得高效的性能。当客户端请求web服务器上的动态脚本时,web服务器会将动态脚本通过tcp协议交给fastcgi主进程,fastcgi主进程根据情况,安排一个空闲的子进程来解析动态脚本,处理完成后将结果返回给wen服务器,web服务器再将结果返回给客户端。该客户端请求处理完毕后,fastcgi子进程并不会随之关闭,而是继续等待主进程安排工作服务
cli
客户端运行模式通过命令行执行脚本语言
web模块模式
Apache方式加载mod_php5.so模块处理php脚本利用web服务器自带的处理器当成模块加载到服务器,随服务器一起启动,无论是否用的PHP解释器都会加载到内存,比较占用内存