手机版

分析PHP中的内存管理 PHP动态分配和释放内存

时间:2021-11-18 来源:互联网 编辑:宝哥软件园 浏览:

内存管理在长时间运行的程序中起着重要的作用,例如服务器守护程序。因此,了解PHP如何分配和释放内存来创建这样的程序是非常重要的。本文将集中讨论PHP的内存管理。首先,它存储在PHP中,填充字符串变量相当简单,只需要一个语句' <?php $ str=' hello world?>',字符串可以自由修改、复制和移动。而在c语言中,虽然你可以写诸如“char * str=‘hello world’;”这么简单的静态字符串;但是,不能修改该字符串,因为它存在于程序空间中。要创建可操作的字符串,必须分配一个内存块,并通过函数(如strdup())复制其内容。复制的代码如下: { char * strstr=str dup(' hello world ');if(!str) {fprintf(stderr,'无法分配内存!');}}由于我们后面会分析的各种原因,传统的内存管理函数(如malloc()、free()、strdup()、realloc()、calloc()等。)几乎不能被PHP源代码直接使用。第二,释放内存几乎存在于所有的平台上,内存管理是通过请求和释放的方式实现的。首先,一个应用程序请求它下面的层(通常称为“操作系统”):“我想使用一些内存空间”。如果有可用空间,操作系统会将其提供给程序并标记,这样就不会将其分配给其他程序。当应用程序用完这个内存时,应该返回给OS;这样,它就可以连续地分配给其他程序。如果程序没有返回这个内存,操作系统就无法知道这个内存是否不再使用,然后重新分配给另一个进程。如果一个内存块没有释放,而所有者应用程序丢失了它,那么我们说这个应用程序有漏洞,因为这部分内存不能再被其他程序使用。在典型的客户端应用程序中,操作系统有时可以容忍较小且不频繁的内存泄漏,因为当进程稍后结束时,泄漏的内存将隐式返回给操作系统。没关系,因为OS知道把内存分配给了哪个程序,可以确定程序终止时不再需要内存。对于长时间运行的服务器守护程序,包括像Apache和扩展php模块这样的web服务器,进程通常被设计为长时间运行。因为操作系统无法清理内存使用,任何程序泄漏——无论多小——都会导致重复操作,最终耗尽所有系统资源。现在,我们不妨考虑一下用户空间中的stristr()函数。为了通过不区分大小写的搜索来查找字符串,它实际上创建了两个字符串中每一个的小副本,然后执行更传统的区分大小写的搜索来查找相对偏移量。但是,在找到字符串的偏移量后,它不再使用这些小写形式的字符串。如果它不释放这些副本,那么每次调用str()的stristr都会泄漏一些内存。最后,web服务器进程将拥有所有的系统内存,但它将无法使用它。您可以自信地说,理想的解决方案是编写好的、干净的和一致的代码。这当然好;然而,在像PHP解释器这样的环境中,这种观点只有一半。三.错误处理为了“跳出”用户空间脚本及其相关扩展函数的活动请求,需要一种方法来完全“跳出”活动请求。这是在Zend引擎中实现的:在请求的开头设置一个“跳出”地址,然后在调用任何die()或exit()或遇到任何严重错误(E_ERROR)时执行一个longjmp()跳转到“跳出”地址。这种‘跳出’的过程虽然可以简化程序执行的过程,但在大多数情况下,意味着会跳过资源清除代码的部分(比如free()调用),最终会导致内存漏洞。

现在,让我们考虑以下处理函数调用的引擎代码的简化版本:复制代码如下: void call _ function(const char * fname,int fname _ len tsrmls _ DC){ Zend _ function * Fe;char * lcase _ fname/* PHP函数名不区分大小写,*为了简化它们在函数表中的定位,*所有函数名都隐式翻译成小写*/lcase_fname=estrndup(fname,fname _ len);zend_str_tolower(lcase_fname,fname _ len);if(Zend _ hash _ find(EG(function _ table),lcase_fname,fname_len 1,(void * *)Fe==FAILURE){ Zend _ execute(Fe-> op _ a

版权声明:分析PHP中的内存管理 PHP动态分配和释放内存是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。