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. PrimeFaces ab function

    The PrimeFaces.ab function is a shortcut function for PrimeFaces.ajax.AjaxRequest. //ajax shortcut a ...

  2. solairs11与solairs10 ftp服务的区别

    Migration from Solaris WU-FTPD to ProFTPD Introduction ------------ This document provides an overvi ...

  3. VirtualBox导入VmWare生成的.vmdk格式虚拟机镜像

    VmWare默认的镜像格式是.vmdk格式的,VirtualBox则默认是.vdi格式的.其实这在VirtualBox新建虚拟机的过程中是可选的. 导入.vmdk格式的镜像到VirtualBox只需要 ...

  4. 数据库基本概念及Oracle基本语句

    一.数据库分类 通常是按照数据模型的特点将传统数据库系统分成网状数据库.层次数据库和关系数据库三种. 1.网状数据库 顾名思义,网状数据库采用的是以记录类型为结点的网状数据模型,是一种导航式(Navi ...

  5. 【NOIP2017提高组模拟12.10】幻魔皇

    题目 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白色节 ...

  6. UVALive 3523 : Knights of the Round Table (二分图+BCC)

    题目链接 题意及题解参见lrj训练指南 #include<bits/stdc++.h> using namespace std; ; int n,m; int dfn[maxn],low[ ...

  7. Python 元组Ⅱ

    删除元组 元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例: 以上实例元组被删除后,输出变量会有异常信息,输出如下所示: 元组运算符 与字符串一样,元组之间可以使用 + ...

  8. WEB上传大文件

    众所皆知,web上传大文件,一直是一个痛.上传文件大小限制,页面响应时间超时.这些都是web开发所必须直面的. 本文给出的解决方案是:前端实现数据流分片长传,后面接收完毕后合并文件的思路.下面贴出简易 ...

  9. [luogu]P1026 统计单词个数[DP][字符串]

    [luogu]P1026 统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1&l ...

  10. HDU 6012 Lotus and Horticulture(离散化)

    题目代号:HDU 6012 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6012 Lotus and Horticulture Time Limit: ...