2006-10-26

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

来源: 天极网 作者:佚名 评论 0 条
 

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_array TSRMLS_CC);
 } else {
  php_error_docref(NULL TSRMLS_CC, E_ERROR,"Call to undefined function: %s()", fname);
 }
 efree(lcase_fname);
}


  当执行到php_error_docref()这一行时,内部错误处理器就会明白该错误级别是critical,并相应地调用longjmp()来中断当前程序流程并离开call_function()函数,甚至根本不会执行到efree(lcase_fname)这一行。你可能想把efree()代码行移动到zend_error()代码行的上面;但是,调用这个call_function()例程的代码行会怎么样呢?fname本身很可能就是一个分配的字符串,并且,在它被错误消息处理使用完之前,你根本不能释放它。

  注重,这个php_error_docref()函数是trigger_error()函数的一个内部等价实现。它的第一个参数是一个将被添加到docref的可选的文档引用。第三个参数可以是任何我们熟悉的E_*家族常量,用于指示错误的严重程度。第四个参数(最后一个)遵循printf()风格的格式化和变量参数列表式样。

  四、 Zend内存治理器

  在上面的"跳出"请求期间解决内存泄漏的方案之一是:使用Zend内存治理(ZendMM)层。引擎的这一部分非常类似于操作系统的内存治理行为-分配内存给调用程序。区别在于,它处于进程空间中非常低的位置而且是"请求感知"的;这样以来,当一个请求结束时,它能够执行与OS在一个进程终止时相同的行为。也就是说,它会隐式地释放所有的为该请求所占用的内存。图1展示了ZendMM与OS以及PHP进程之间的关系。

深入探讨PHP中的内存治理问题
图1.Zend内存治理器代替系统调用来实现针对每一种请求的内存分配。


  除了提供隐式内存清除功能之外,ZendMM还能够根据php.ini中memory_limit的设置控制每一种内存请求的用法。假如一个脚本试图请求比系统中可用内存更多的内存,或大于它每次应该请求的最大量,那么,ZendMM将自动地发出一个E_ERROR消息并且启动相应的"跳出"进程。这种方法的一个额外优点在于,大多数内存分配调用的返回值并不需要检查,因为假如失败的话将会导致立即跳转到引擎的退出部分。

  把PHP内部代码和OS的实际的内存治理层"钩"在一起的原理并不复杂:所有内部分配的内存都要使用一组特定的可选函数实现。例如,PHP代码不是使用malloc(16)来分配一个16字节内存块而是使用了emalloc(16)。除了实现实际的内存分配任务外,ZendMM还会使用相应的绑定请求类型来标志该内存块;这样以来,当一个请求"跳出"时,ZendMM可以隐式地释放它。

  经常情况下,内存一般都需要被分配比单个请求持续时间更长的一段时间。这种类型的分配(因其在一次请求结束之后仍然存在而被称为"永久性分配"),可以使用传统型内存分配器来实现,因为这些分配并不会添加ZendMM使用的那些额外的相应于每种请求的信息。然而有时,直到运行时刻才会确定是否一个特定的分配需要永久性分配,因此ZendMM导出了一组帮助宏,其行为类似于其它的内存分配函数,但是使用最后一个额外参数来指示是否为永久性分配。
共3页: 上一页 [1] 2 [3] 下一页
(本文仅表明作者个人观点,不代表本站及其管理员立场.) 推荐 收藏 投稿 打印 返回 关闭
上一篇:10个重要的PHP网络信息函数说明  
下一篇:PHP语言发展历史
    评论加载中…
 推荐文章
     

网站首页  -  网站地图 -   站长论坛  -  网站投稿  -    -  网站管理
Copyright © 2008 芜湖站长站 All Rights Reserved 皖ICP备07500611号