PHP内存模拟分析

值传递:将一个变量的值,复制一份,把新的这份交给另外一个变量保存,从而在内存中产生两个变量,对应两个不同的值,任何一个的修改都不会影响彼此。

$变量1 = 值;
$变量2 = $变量1;

引用传值:变量实际保存的是数据对应的内存地址,如果将一个变量所保存的内存地址赋值给另外一个变量,存在两个变量共同指向同一块内存地址,一个变量的修改会导致另外一个变量的修改。 引用传递必须在被传递的变量之前使用地址符号:&

$变量1 = 值;
$变量2 = &$变量1; // 取$变量1的地址

内存分析

内存都是分为以下几个部分:

  • 栈区:是程序所能操作的理论上唯一的内存区域,内存很小,但是效率最高。
  • 堆区:是唯一的内存地址连续的内存,内存很大,但是效率最低。
  • 代码段:装载代码的内存,程序要运行,必须先将代码装载到代码段,然后在代码段里面逐行的运行程序代码。
  • 数据段:是普通数据存储的内存,里面通常还分为两块区域: 全局区存放普通数据;静态区存储常量和静态数据。

在内存中,程序所能操作的只有栈区,数据段和堆区都是由栈区来操作

PHP代码的执行

PHP是一种高级语言(接近自然语言),所以不可能被计算机直接解析(计算机只能识别机器码(二进制))。

  1. 将所有的脚本(代码)加载到内存(代码段)
  2. 编译(词法分析、语法分析)
  3. 生成opcode:机器可以执行的代码(二进制)
  4. zendEngine(zend引擎)解析opcode,返回执行结果 

PHP代码内存分析

  1. 将代码加载到代码段:编译
  2. 逐行的执行代码
  3. PHP将执行结束的结果返回

举个例子

// 定义变量
$f = 1;
$s = $f; // 值传递
$t = &$f; // 引用传递

const PI = 3.14;

// 修改变量
$s = 2;
$t = 3;

// 输出
echo $f,$s,$t;

1.加载源代码:编译(对代码进行优化)将代码加载到代码段

2.执行代码
2.1执行$f = 1;
①在栈区开辟空间存储$f
②在全局区开辟内存存储数据1
③将1所在内存地址赋值给$f变量

2.2执行$s = $f;
①在栈区开辟空间存储$s
②取得$f所存储地内存地址里面保存的数据1
③在全局区开辟一块新的内存地址保存值1
④将新的值1的内存地址赋值给$t

2.3执行$t = &$f;
①在栈区开辟空间存储$t
②获取$f所存储的内存地址
③将取出来的内存地址赋值给$t

2.4执行const PI = 3.14;
①在栈区开辟空间保存PI
②在静态区开辟内存存储3.14
③将3.14的内存地址赋值给PI

2.5执行$s = 2;
①找到$s变量所指向的内存地址
②修改原来的值为2

2.6执行$t = 3;
①找到$t变量所指向的内存地址
②修改原来的值为3

2.7执行echo $f,$s,$t;
通过变量找到内存地址,取出里面的值并输出:3,2,3

3.脚本执行结束:释放所有的内存(栈区和代码段)
3.1代码段自动释放

3.2释放所有程序内存(栈区)

3.3操作系统回收内存:凡是没有被引用的全部回收

总结:当程序在执行中会占用内存,执行完毕后,内存全部被回收。

原文地址:https://www.cnblogs.com/chenjiacheng/p/6522617.html