background image

OS 知道它把该内存分配给了哪个程序,并且它能够确信当该程序终止时不再需要该内存。

  
  而对于长时间运行的服务器守护程序,包括象 Apache 这样的 web 服务器和扩展
php 模块来说,进程往往被设计为相当长时间一直运行。因为 OS 不能清理内存使用,所
以,任何程序的泄漏-无论是多么小-都将导致重复操作并最终耗尽所有的系统资源。
  
  现在,我们不妨考虑用户空间内的 stristr()函数;为了使用大小写不敏感的搜索来查
找一个字符串,它实际上创建了两个串的各自的一个小型副本,然后执行一个更传统型
的大小写敏感的搜索来查找相对的偏移量。然而,在定位该字符串的偏移量之后,它不再
使用这些小写版本的字符串。如果它不释放这些副本,那么,每一个使用 stristr()的脚本
在每次调用它时都将泄漏一些内存。最后,web 服务器进程将拥有所有的系统内存,但
却不能够使用它。
  
  你可以理直气壮地说,理想的解决方案就是编写良好、干净的、一致的代码。这当然不
错;但是,在一个象 PHP 解释器这样的环境中,这种观点仅对了一半。
  
  三、错误处理
  
  为了实现"跳出"对用户空间脚本及其依赖的扩展函数的一个活动请求,需要使用一
种方法来完全"跳出"一个活动请求。这是在 Zend 引擎内实现的:在一个请求的开始设置
一个"跳出"地址,然后在任何 die()或 exit()调用或在遇到任何关键错误(E_ERROR)时执
行一个 longjmp()以跳转到该"跳出"地址。
  
  尽管这个"跳出"进程能够简化程序执行的流程,但是,在绝大多数情况下,这会意
味着将会跳过资源清除代码部分(例如 free()调用)并最终导致出现内存漏洞。现在,让我
们来考虑下面这个简化版本的处理函数调用的引擎代码:
  
  以下为引用的内容:
  
  voidcall_function(constchar*fname,intfname_lenTSRMLS_DC){
  
  zend_function*fe;
  
  char*lcase_fname;
  
  /*PHP 函数名是大小写不敏感的,
  
  *为了简化在函数表中对它们的定位,
  
  *所有函数名都隐含地翻译为小写的
  
  */