• PHP:执行模型和内存模型


    背景

    对于任何一种语言,了解其执行模型和内存模型都是有意义的,本文中的内容不见得正确,请多批评。

    执行模型

    每个请求都是一个独立的PHP进程,两个请求之间会完全隔离,会话和Cookie是通过其他机制在多个请求之间实现数据共享,像静态变量和全局属性这些会在每个请求中重新初始化。

    示例

    1 <?php
    2 static $StaticVar = 1;
    3 $StaticVar++;
    4 
    5 echo $StaticVar.'<br/>';
    6 ?>

    结果

    2 //无论刷新多少次请求,结果都是2。

    内存模型

    基本规则

    以下是PHP的内存管理规则:

    • 默认按值传递。
    • 必须显式的声明按引用传递。
    • 对象类型的值是对象的地址
    1 $symbol = value;

    其中:symbo是符号,存放在符号表中(全局符号表或活动符号表),value是符号引用的值。

    1 $symbol_ref = &$symbol;

    其中:symbo_ref和symbo会l引用同一个值。

    第一个小测试

    代码

     1 <?php
     2 $var_a = 1;
     3 $var_b = $var_a;
     4 $var_c = &$var_a;
     5 $var_d = $var_c;
     6 $var_e = &$var_c;
     7 $var_e = 2;
     8 
     9 echo "var_a:$var_a, var_b:$var_b, var_c:$var_c, var_d:$var_d, var_e:$var_e<br/>"
    10 
    11 ?>

    结果

    1 var_a:2, var_b:1, var_c:2, var_d:1, var_e:2

    内存变化

    第一步

    第二步

    第三步

    第四步

    第五步

    第六步

    第二个小测试

    代码

     1 <?php
     2 class TestClass {
     3     private $value = 1;
     4     
     5     function setValue($value) {
     6         $this->value = $value;
     7     }
     8     
     9     function getValue() {
    10         return $this->value;    
    11     }
    12 }
    13 
    14 $var_obj = new TestClass();
    15 $var_obj_copy = $var_obj;
    16 $var_obj_ref = &$var_obj;
    17 
    18 $var_obj_ref->setValue(2);
    19 
    20 echo $var_obj->getValue().'<br/>';
    21 echo $var_obj_copy->getValue().'<br/>';
    22 echo $var_obj_ref->getValue().'<br/>';
    23 ?>

    结果

    1 //输出结果
    2 
    3 2
    4 2
    5 2

    内存变化

    第一步

    第二步

    第三步

    第四步

    备注

    真正的PHP内存不是上面那样,但是语义上和上面描述的没有区别,PHP为了优化内存做了一些额外的工作

    PHP为了提高内存利用效率,并不是在赋值给符号的时候立即按值拷贝的,每个值都维护了一个引用计数(被多少个符号引用了),在某些合适的时刻会自动拷贝,不过这些时刻对于开发人员是透明的,可以不用考虑。

    有感兴趣的朋友,可以参考这篇文章:http://www.laruence.com/2008/09/19/520.html

  • 相关阅读:
    Golang Struct 声明和使用
    docker 中ulimit设置理解
    微服务架构引入的问题及解决方案
    Jenkins 集成Sonar代码质量扫描
    Jenkins和gitlab集成自动构建
    初识微服务架构
    jenkins 集成钉钉机器人通知
    Go 新起点
    shell中的(),{}几种语法用法
    二进制日志配置和运维管理
  • 原文地址:https://www.cnblogs.com/happyframework/p/3254007.html
Copyright © 2020-2023  润新知