析构函数与回收机制
当一段PHP脚本全部执行完毕之后,PHP的垃圾回收机制起到了作用,它将对象进行了释放;
对象的回收机制
在PHP中对象是引用传值
示例:
class Ren {
public $name = '小明';
public function __construct(){
echo '构造';
}
public function __destruct(){
echo '析构';
}
}
$a = new Ren();
$d = $c = $b = $a;
/*这里的四个对象:$a,$b,$c,$d都是同一个实例对象,四个对象中任意修改其中一个都会影响到其他三个,而如果是这样:
$a = new Ren();
$b = new Ren();
$c = new Ren();
$d = new Ren();
那么则修改任意一个实例对象,都不会影响其他实例;
为什么?
因为对象的赋值是按引用赋值的,引用就是指向内存中实际存储对象的地址;
那么$d = $c = $b = $a;在new Ren()的时候返回的是一个对象,这个对象的引用赋值给了$a ,后面是同一个意思,$b被赋值未new Ren()的引用,四个实例对象的引用都是同一个,既然他们指向的都是同一个对象,那么其中一个修改了内存中的对象,其他实例对象也是指向那个内存的对象,所以,会影响所有指向这个对象的实例对象;
而第二种,每次实例化对象时,都会进行重新的在内存中分配空间,new Ren();四个实例对象指向的不是同一个内存中的对象;
*/
总结:
- 一个对象被多个实例引用,其中任意一个实例被销毁,实际的对象不会销毁,当对象没有被其他实例对象引用时,对象销毁;
- 脚本运行完毕,即使是还有实例对象引用对象,那么,依旧会被销毁;
一个简单的内存回收机制的题目
class Ren{
public $name = '张三';
public function __construct(){
echo '我是构造函数';
}
public function __destruct(){
echo '我是析构函数';
}
}
$a = new Ren();
$d = $c = $b = $a;
echo $a -> name;
echo $a -> name;
$c -> name = '李四';
echo $a -> name;
echo $a -> name;
unset($a);
echo '脚本的最后一行输出';
/*
问:输出的顺序是什么?
答:
我是构造函数
张三
张三
李四
李四
脚本的最后一行输出
我是析构函数
*/
垃圾回收的方式
- 引用计数
- 标记清除
- 标记缩并
- 节点拷贝
- 分代收集
- 如果垃圾回收机制不好,可能会导致一门语言的性能差,耗资源等问题;