频道直达 - 专题 - 新闻 - 基础 - 高级 - 安装 - 技巧 - 数据库 - 手册 - PHP - Linux - Java - MySQL - Apache - 麻辣堂 - 狼盟 - Rails社群 - 搜索 - 下载 - 开源 - 论坛
PHP开发资源网 主页>>高级应用>> 收藏此文 | 收藏本站 | 设为首页

php扩展开发学习笔记 7

来源:www.phpres.com 作者:Angelover 出处:www.phpres.com 2008-6-28 10:05:49 进入讨论组
关 键 词: 笔记 学习 开发 扩展 zval 一个 引用 变量 refcount 时候

引用计数

  php采用的内存管理和垃圾回收方法是基于引用计数的。之前说过,在zval结构里有一个refcount是表示引用计数,还有一个is_ref表示是否是个引用变量。那么php代码的实际运行中,又是如何处理的呢?

  比如这样的php代码:
$a = "hello";
$b = $a;
这时候并不像很多人认为的那样,在内存里把"hello"这个字符串复制了一份,而只是把$b指向了和$a对应的同一个zval,然后把那个zval的refcount + 1。这样避免了一次内存拷贝。但如果在这之后改变了其中一个变量的值,比如$b.= " world";又会如何呢?这时候才会分配一个新的zval给$b,然后把原先那个zval的refcount - 1。这就是传说中的copy on write。就是说,在改变值得时候才会有内存拷贝。

  那么引用变量又会如何呢? 比如
$a = "hello";
$b = &$a;
和前面一样,$a, $b还是指向同一个zval。只是还要把这个zval的is_ref置为1。之后再改变$a或者$b的时候就不会再发生拷贝。那么
$a = "hello";
$b = &$a;
$c = $a;
这时又会如何呢?因为$c并不是一个引用变量,因此不能和$a, $b共用一个zval。因此在$c = $a的时候会直接产生一个新的zval。

  因此,在php中,使用引用对改善性能并不会有多少作用,通常情况下还会使情况更糟。所以,引用还是只在真正需要的时候才用为好。

  再说说垃圾回收。每个zval都有一个refcount表示它的变量的引用数。不管对于普通变量还是引用变量都是如此。refcount的初始值一般为1。每当增加一个引用时就+1,减少一个引用,比如unset时就会-1。当refcount为0的时候,php就会把它释放掉。这就是基于引用计数的垃圾回收方法。

使用zval

初始化zval
MAKE_STD_ZVAL(zval*);
这个宏的左右是创建一个zval,完成初始化(如将ref_count置为1,isref置为false)并把指针赋给参数。

赋值
写扩展的时候不可避免的要用到把一个zval复制到另一个zval,就是类似$a = $b;的操作。对于简单的值或许手动维护引用计数之类的还不算很麻烦但对于数组,对象之类的就需要一层层递归进去,因此就有了一个zval_copy_ctor来做着件事情。
原有一个zval* p_zval_b,
zval* p_zval_a;
MAKE_STD_ZVAL(p_zval_a); //初始化p_zval_a
*p_zval_a = *p_zval_b;
zval_copy_ctor(p_zval_a);
这里,zval_copy_ctor完成了类似赋值的操作,包括引用计数处理,对于hash值的成员处理等。

 释放一个zval则是使用zval_ptr_dtor(**zval)。注意它的参数。它会释放掉为这个zval所分配的内存。

欢迎进入PHP开发资源论坛讨论。
收藏此文】【 】【打印】【关闭
相关文章
图文推荐
论 坛 资 源
PHP开发资源网奋斗目标
阅读排行:
热门技术文档
最新图文档
本站编辑推荐:(本站开通Delphi4PHP专区,欢迎进入论坛交流!)
编缉最近更新文章
网站赞助商
搜索您感兴趣的内容
 
   网站首页 -  网站地图 -  网站合作 -  手册中心 -  通用网址 -  网站论坛 -  网站投稿 -  友情链接 -  帮助中心
版权所有:PHP开发资源网 © 2003-2008 通用网址:PHP资源网 合作媒体: 赛迪网IT技术
互联网违法和不良信息举报中心 | 不良信息举报信箱