php5在引入引用计数后,使用了refcount_gc来记录次数,同时使用is_ref_gc来记录是否是引用类型。

例如

$a = 'hello';

//$a->zval1(type=IS_STRING,refcount_gc=1,is_ref_gc=0)

这个时候$a指向一个结构体,主要看refcount_gc=1,这就是引用计数字段,因为hello这个字符串被赋值给了$a,所以这个时候hello的引用计数就是1

$b = $a;

$b,$a->zval1(type=IS_STRING,refcount_gc=2,is_ref_gc=0)

这个时候又把$a赋值给了$b,所以这个时候$b和$a同时指向这个结构体,并且引用计数加1

$c = &$b;

//$a->zval1(type=IS_STRING,refcount_gc=1,is_ref_gc=0)

//$c,$b->zval2(type=IS_STRING,refcount_gc=2,is_ref_gc=1)

这个时候因为把$b赋值给了$c,但是是传址的方式,所以在这个时候就要分离了,$a还指向原来的结构体,$c和$b同时指向一个新的结构体,这个时候zval的is_ref_gc值会改变,使得此时的zval必须进行分离,但是实际上他们的值还没有变化,这使得需要在堆中维护两个值为"hello"的zval。

下面我们来看看php7中的实现

php7引入了新的类型IS_REFERENCE来处理这个问题,首先看看zend_reference的结构体:

struct _zend_reference{

zend_refcounted_h gc;

zval val;

};

$a = 'hello';

//$a->zend_string(refcount=1,val)

$b = $a;

//$b,$a->zend_string(refcount=2,val)

$c = &$b;

//$a->zend_string(refcount=2,val)

//$c,$b->zval(type=IS_REFERENCE,refcount=2)->zend_string(refcount=2,val)

从上面可以看出来,当使用&操作时,会创建一种新的中间结构体zend_referenct,这个结构体会指向真正的zend_string结构体,所以zend_string结构体的引用计数不变,同时zend_reference结构体的引用计数变为2,因为$c和$b此时的类型都会变为zend_reference,这样的好处是原始的zend_string在内存中始终只有一份(避免了由于字符串的重复申请导致的内存浪费),更加易于维护。

PHP5和PHP7引用对比(笔记)的更多相关文章

  1. (转)添加服务引用和添加Web引用对比

    在WindowsForm程序中添加服务引用和Web引用对比 为了验证书上有关Visual Studio 2010添加服务引用和Web引用的区别,进行实验. 一.建立一个Web服务程序项目新建项目,选择 ...

  2. 添加服务引用和添加Web引用对比

    原文:添加服务引用和添加Web引用对比 在WindowsForm程序中添加服务引用和Web引用对比 为了验证书上有关Visual Studio 2010添加服务引用和Web引用的区别,进行实验. 一. ...

  3. PHP5和PHP7的安装、PHP和apache的整合!

    1.PHP5的安装: 下载: wget -c http://cn2.php.net/distributions/php-5.6.36.tar.gz  (php5) wget -c http://cn2 ...

  4. 安装最新版的wampserver,可以兼容php5和php7

    本文介绍的wamp是Windows+Apache+MySQL+PHP+phpMyAdmin,主要应用于开发环境[一键安装包,简单好用]. 这是运行在Windows系统下的官方安装包,可以快速的搭建属于 ...

  5. java中引用对比C++指针

    前置知识地址:https://blog.csdn.net/wangfei8348/article/details/51383805 重点在后面的引用对比实验(测试出内存地址,我很开心哈哈哈,客观给个好 ...

  6. 在Apache中安装php5.6 & php7.3

    1.下载 httpd-2.4.41-win64-VC15.zip.php5.6 +  vc11.  php7.3  + vc14-16 2.配置httpd,在 httpd.conf L180 添加如下 ...

  7. php5与php7安全性的区别

    0X01 前言 本篇文章大多为转载,但是修正了一些不正确的说法,对某些功能点的变更指出具体是哪个版本变更,加入了一些小更新. (原文地址:https://www.freebuf.com/article ...

  8. nginx下配置php5和php7

    用的是lnmp 一键安装的 php5.6版本网上百度Ubuntu安装多版本PHP就行 参考文章原链接:http://blog.csdn.net/21aspnet/article/details/476 ...

  9. wamp集成环境php多版本搭建(php5.5,php5.6,php7.0.6)

        首先需要搭建的版本可以在php官方(http://windows.php.net/download)下载对应的版本,X86对应的是32位操作系统,X64对应的是64位操作系统.    1:下载 ...

随机推荐

  1. Python 分页和shell命令行模式

    前言 除了手动添加你的文章后外,你还可以用命令行来添加,python 自带了一种命令行 就是 shell 快速添加博文:Shell命令行模式 在你的目录下:mysite python manage.p ...

  2. 购物网站被p.egou.com强制恶意劫持

    今天早上打开电脑浏览京东,发现随便点击商品,都自动转化为淘客推广的页面, 我以为是360浏览器自己干的,然后我换了谷歌,也是一样,难道这是电脑里面有流氓插件? 我又换了火狐,还是一样,没办法了,换IE ...

  3. JAVA笔记18-容器之二增强的for循环(不重要)

    JDK1.5增强的for循环(foreach??)

  4. 【ZJOJ5186】【NOIP2017提高组模拟6.30】tty's home

    题目 分析 如果直接求方案数很麻烦. 但是,我们可以反过来做:先求出所有的方案数,在减去不包含的方案数. 由于所有的路径连在一起, 于是\(设f[i]表示以i为根的子树中,连接到i的方案数\) 则\( ...

  5. 【NOIP2012模拟10.25】旅行

    题目 给定一个n行m列的字符矩阵,'.'代表空地,'X'代表障碍.移动的规则是:每秒钟以上下左右四个方向之一移动一格,不能进入障碍. 计算:在空地中随机选择起点和终点(可以重合,此时最短耗时为0),从 ...

  6. 网络吞吐量(network)

    题目 分析 过一遍spfa,把从点1到其他每一个点的最短路求出来, 接着递归把所有最短路径上的路径保留,其他的删掉. 对于保留的路径作为网络流的边,流量为无穷大,对于每个点拆点两个点之间的流量为吞吐量 ...

  7. netty-socketio(二)整合redis实现发布订阅

    1.Redis 发布订阅 参考:https://www.runoob.com/redis/redis-pub-sub.html Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub ...

  8. Redis缓存雪崩和缓存穿透等问题

    穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透. 解决办法:①用一个bitma ...

  9. Mybatis 中在xxx.mapper书写模糊查询

    1.在mybatis中,书写sql,有时候会有一些不细心,如: <!-- 首页商品 关键字搜索--> <select id="getGoodsByLikeTitle&quo ...

  10. JDK源码--HashMap(之resize)

    1.HashMap源码阅读目标了解具体的数据结构(hash及冲突链表.红黑树)和重要方法的具体实现(hashCode.equals.put.resize...) 2.重要方法 hashCode 与 e ...