深入探讨PHP中的内存管理问题.docxVIP

  • 0
  • 0
  • 约1.19万字
  • 约 12页
  • 2019-11-26 发布于广东
  • 举报
深入探讨PHP中的内存管理问题 更新日期:2006-10-26 08:53出处:夭极开发 作者:朱先忠编译 摘要内存管理刈于长期运行的程序,例如服务器守护程序,是相当重要的影响;因此 理解PHP是如何分配与释放内存的对于创建这类程序极为重要。本文将重点探讨PHP的内 存管理问题。 一、内存 在PHP中,填充一个字符串变量相当简单,这只需要一个语句y?php $str = hello world ?”即可,并且该字符串能够被白由地修改、拷贝和移动。而在C语言中,尽管你 能够编写例如”char *str = “hello world “;”这样的一个简单的静态字符串;但是,却不能 修改该字符串,因为它生存于程序空间内。为了创建一个可操纵的字符串,你必须分配一个 内存块,并且通过一个函数(例如strdup())來复制其内容。 { char *str; str = strdup(Hhello world*1); if (!str) { fprintf(stderr? Unable to allocate memory!”); } rfi于后面我们将分析的各种原因,传统型内存管理函数(例如malloc(), free(), strdu p(), realloc(), calloc() ,等等) 几乎都不能直接为PHP源代码所使用。 二、释放内存 在几乎所有的平台上,内存管理都是通过一种请求和释放模式实现的。首先,一个应用 程序请求它下面的层(通常指”操作系统”)「我想使用一些内存空间“。如果存在可用的空间, 操作系统就会把它提供给该程序并且打上一个标记以便不会再把这部分内存分配给其它程 序。 当应用程序使用完这部分内存,它应该被返回到OS;这样以來,它就能够被继续分配给其 它程序。如杲该程序不返回这部分内存,那么OS无法知道是否这块内存不再使用并进而再 分配给另一个进程。如果一个内存块没有释放,并且所有者应用程序丢失了它,那么,我们 就说此应用程序”存在漏洞”,因为这部分内存无法再为其它程序可用。 在一个典型的客户端应用程序屮,较小的不太经常的内存泄漏有时能够为OS所”容忍”, 因为在这个进程稍后结朿时该泄漏内存会被隐式返回到OS。这并没有什么,因为OS知道 它把该内存分配给了哪个程序,并且它能够确信当该程序终止时不再需要该内存。 而对于长时间运行的服务器守护程序,包括象Apache这样的web服务器和扩展php 模块来说,进程往往被设计为相当长时间一直运行。因为OS不能清理内存使用,所以,任 何程序的泄漏■无论是多么小■都将导致重复操作并最终耗尽所有的系统资源。 现在,我们不妨考虑用户空间内的stristr()函数;为了使用大小写不敏感的搜索来查找 一个字符串,它实际上创建了两个串的各自的一个小型副本,然后执行一个更传统型的大小 写敏感的搜索来查找相对的偏移量。然而,在定位该字符串的偏移暈Z后,它不再使用这些 小写版本的字符串。如果它不释放这些副本,那么,每一个使用stristr()的脚本在每次调用 它时都将泄漏一些内存。最后,web服务器进程将拥有所有的系统内存,但却不能够使用 它。 你可以理直气壮地说,理想的解决方案就是编写良好、干净的、一致的代码。这当然不 错;但是,在一个象PHP解释器这样的环境屮,这种观点仅对了一半。 三、错误处理 为了实现”跳岀”对用户空间脚木及其依赖的扩展函数的一个活动请求,需要使用一种方 法来完全”跳出”一个活动请求。这是在Zend引擎内实现的:在一个请求的开始设置一个” 跳出”地址,然后在任何die()或exit()调用或在遇到任何关键错误(E_ERROR)时执行一个Io ngjmp()以跳转到该”跳出“地址。 尽管这个”跳出”进程能够简化程序执行的流程,但是,在绝大多数情况下,这会意味看 将会跳过资源清除代码部分(例如free()调用)并最终导致出现内存漏洞。现在,让我们来考 虑下面这个简化版本的处理函数调用的引擎代码: void call_function(const char *fname, int fnarnejen TSRMLS_DC){ zend_function *fe; char *lcase_fname; /* PHP函数名是大小写不敏感的, *为了简化在函数表中对它们的定位, 水所冇函数名都隐含地翻译为小写的 */ lcase_fname = estrndup(fname, fname_len); zend_str_tolower(lcase_fname, fname_len); if (zcnd_hash_find(EG(function_tablc) lcasc_fnamc, fnamc_lcn + 1, (void **)fc) == FAILURE) { zend_

文档评论(0)

1亿VIP精品文档

相关文档