从php引用变量引出php的垃圾回收机制

什么是引用变量。如果同学们知道linux中的硬链接的话,那么就非常容易理解php的引用变量了。在linux中,给一个文件做了硬链接之后,通过源文件和链接文件都可以访问到源文件的内容。php中的引用变量非常类似于linux中的硬链接,通过不同的变量名来访问同样的内容。

定义引用变量

在php中是通过&符号来定义引用变量的。下面我们来通过一个实例来看看php中引用变量的特性

<?php

$a = 100;
$b = $a;

$b = 200;
echo $a;  // 100

可以看到通过普通的复值操作,当变量$b的值改变的时候,$a的值没有改变。这是因为,普通的赋值操作,会在内存空间重新开辟一个地址分配给新的变量$b。所以当$b内容改变时,不会影响到$a。

下面,我们用引用变量来试试,看会不会有什么不同。

<?php

$a = 100;
$b = &$a;

$b = 200;
echo $a;  // 200

和上面的代码几乎完全一样,只是多了一个&符号,结果就完全不一样的。$b变量的改变会让$a也跟着改变。

当使用引用变量的时候,php不会再内存空心开辟一块空间,而是公用之前变量的内存地址。这个时候,只要指向该内存地址的变量中任意一个变量改变了内容,其他的变量内容也都会改变。

对象的赋值默认使用引用传递方式

和一般变量不同的是,对象的赋值采用的引用。原因是对象和一般变量不同,它占用的空间会大一些,采用引用可以减少内存的占用。如不想使用引用方式的话,可以使用clone来完成。

class Person 
{
   public $name = 'gwx';
   public $age  = 28;
}

$obj1 = new Persion;
$obj2 = $obj1;  // 引用方式

$obj3 = clone $obj1; // 普通赋值方式

php垃圾回收机制

我们知道通过unset可以来删除一个变量,那么他是通过什么样的机制来删除变量的呢?其实unset是通过取消变量对内存地址的引用,来达到删除变量的作用,但它并不会回收内存空间。回收内存空间是php自身的垃圾回收机制来完成的。

php的垃圾回收机制大体上是这样的,当一块内存空间地址没有一个变量去引用他时,该空间地址就会被回收。

下面我们来看一个例子:

$a = 100;
$b = &$a;
unset($b);

echo $a; // 100;

可以看到,当我们unset变量b后,变量a并没有受到影响,依旧还是存在。因为我们只是把变量b对内存地址的引用给删除掉了,还有变量a依旧引用,所以不会触发垃圾回收机制。