而对于长时间运行的服务器守护程序,包括象
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 函数名是大小写不敏感的,
*为了简化在函数表中对它们的定位,
*所有函数名都隐含地翻译为小写的
*/
lcase_fname=estrndup(fname,fname_len);