起因

因为感兴趣于unset($var)和$var=null的区别,于是找了一个stackoverflow高分问题及答案,翻译以供参考。

注:以下的问题和答案翻译自http://stackoverflow.com/questions/584960/whats-better-at-freeing-memory-with-php-unset-or-var-null

问题篇

Q:

我意识到第二个方法避免了函数调用的消耗(更新,实际是语言结构),但是我对于哪一个更好很有兴趣。我过去常常使用unset(),但是我看到很多受人尊敬的类使用$var=null替代。哪一个更适合为什么?

答案篇

A1

unset就像其名字所说的一样-删除一个变量。他不强制立即释放缓存。PHP的“垃圾”在适当的时候将会回收-出于速度的角度考虑,在CPU周期或者直到内存耗尽之前,无论发生什么,都不释放内存。

如果你正在使用$whatever=null,将会重写变量的数据。你本想使内存释放、缩小地更快,但是可能会占用CPU周期,导致总体执行时间更长。

2013年后,PHP Manual不再包含这个区块。

值得注意的是:PHP5.3之前,如果你有两个处于循环引用的对象,比如是“父子”类的关系,父类实例调用unset方法,将不会释放使用父类引用的子类的内存。(当父实例被垃圾回收时,也不会释放内存。)

上边那句话结合代码就很好理解了:

class Test{
public $var = 'test variable';
}
while(true){
$test = new Test();
$test->test = $test;
unset($test);
}

以上代码在PHP5.3之前,运行后,内存占用持续增加,最终导致 “PHP Fatal error: Allowed memory size of xxxxx bytes exhausted”。但这并不是这篇文章的重点(作者注:之后的博客会介绍自己对“PHP垃圾回收”的理解),暂且只列出的解决办法:

class Test{
public $var = 'test variable';
}
while(true){
$test = new Test();
$test->test = $test;
unset($test->test);//先删除掉引用变量
unset($test);
}

使用unset($var)会把$var从符号表删除。比如:

$var = 'hello world';
unset($var);
var_dump($var);
//output:undefined $var

当使用$a=null时:

$var = 'hello world';
$var = null;
var_dump($var);
//output:null

看起来$var=null比unset($var)要快一些:因为更新符号表条目比删除它更快(作者注:PHP版本不同而不同)。

当你删除一个不存在的变量时,将会触发一个错误,变量表达式的值将也会是null。

如果一个变量设置成了null,仍将是一个的普通变量。

A2

unset实际上不是一个函数,而是一个语言结构体。

不考虑性能,使用unset使你的代码更加清晰。

A3

有回答者做了一个实验比较unset和赋值null,实验代码如下,实验PHP版本包括PHP5.1-5.4,PHP5.0和PHP4.4,我对PHP5.6、PHP7.0、PHP7.1作了补充(作者注:实验结果可能跟机器配置有关系)。

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n"; $start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
版本 null执行时间(s) unset执行时间(s) null和unset哪个更快
PHP7.1 0.22593188285828 0.19007802009583 unset
PHP7.0 0.54828405380249 0.60010099411011 null
PHP5.6 0.72876906394958 1.9859180450439 null
PHP5.4 0.88389301300049 2.1757180690765 null
PHP5.3 1.7235369682312 2.9490959644318 null
PHP5.2 3.0069220066071 4.7002630233765 null
PHP5.1 2.6272349357605 5.0403649806976 null
PHP5.0 10.038941144943 7.0874409675598 unset
PHP4.4 7.5352551937103 6.6245851516724 unset

翻译自:

http://stackoverflow.com/questions/584960/whats-better-at-freeing-memory-with-php-unset-or-var-null

PHP中unset和null的比较的更多相关文章

  1. win10 uwp Window.Current.Dispatcher中Current为null

    本文说的是进行网络中异步界面出现的错误,可能带有一定的主观性和局限性,说的东西可能不对或者不符合每个人的预期.如果觉得我有讲的不对的,就多多包含,或者直接关掉这篇文章,但是请勿生气或者发怒吐槽,可以在 ...

  2. [转帖]shell 中的>/dev/null 2>&1 是什么鬼?

    shell 中的>/dev/null 2>&1 是什么鬼? http://blog.jobbole.com/109355/ 背景 我们经常能在shell脚本中发现>/dev/ ...

  3. C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现

    C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现 来源 http://blog.csdn.net/Virtual_Func/article/details/4975 ...

  4. 在python中是没有NULL的,取而代之的是None,它的含义是为空

    在python中是没有NULL的,取而代之的是None,它的含义是为空

  5. webapi中session为null的解决方案

    Session  webapi中session为null的解决方案 在Global.asax里添加:开启Session功能(默认是不开启) 重写init方法 public class WebApiAp ...

  6. 160304-02、JS 中如何判断null 和undefined

    JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正确的用法: var exp = undef ...

  7. iOS之iOS中的(null)、<null>、 nil 的问题

      摘要: 你有没有过这样的经历,就是界面上显示出类似<null>.(null)这样一些东西,有时候还会莫名其妙的闪退.反反复复真是曰了犬,今天来总结一下这个问题的解决方法 前段时间开发过 ...

  8. 我的Android进阶之旅------>android中service的onStartCommand()方法中intent为null的问题

    今天在维护公司的一个APP的时候,突然爆了空指针异常, Caused by: java.lang.NullPointerException: Attempt to invoke virtual met ...

  9. 在Java中,return null 是否安全, 为什么?

    Java代码中return value 为null 是不是在任何情况下都可以,为什么不会throw NullPointerException? Java语言层面:null值自身是不会引起任何问题的.它 ...

随机推荐

  1. UVA 11355 Cool Points( 极角计算 )

    We have a circle of radius R and several line segments situated within the circumference of this cir ...

  2. 使用autoconf和automake生成Makefile

    使用环境: 我的是Ubuntu 16.04,需要用到autoconf和automake,没有的话自行安装. 以helloworld为例: 1.首先新建一个文件夹然后进去没的说:然后自然得先写出那个著名 ...

  3. Ubuntu中实现Docker内安装jenkins+jenkins远程触发

    前面做了在ubuntu中安装jenkins+docker实现自动部署,但是得安装jdk8+tomcat8环境,比较麻烦,因此本文记录如何将jenkins直接装在dockers内并且实现远程触发功能. ...

  4. Eclipse如何构建(普通web)Maven工程

    进行以下步骤的前提是你已经安装好本地maven库和eclipse中的maven插件了(有的eclipse中已经集成了maven插件) 一.Maven项目的新建 1.鼠标右键---->New--- ...

  5. Update Vim to 8.0 in Ubuntu

    add PPA sudo add-apt-repository ppa:jonathonf/vim Update and Install sudo apt-get update sudo apt-ge ...

  6. Dictonary(Python)(一)

    基本用法: .keys .values .items >>> D = dict(a=1,b=2,c=3) >>> D {'a': 1, 'b': 2, 'c': 3 ...

  7. IDEA使用Maven搭建JavaWeb项目

    1. 新建项目 2. 填写项目坐标信息 3. 手动生效pom.xml 4. 添加maven常用配置 1) 设置项目统一编码 <!-- 设置编码 --> <properties> ...

  8. Centos MySQL 5.7安装、升级教程

    MySQL 5.7安装.升级笔记分享: 卸载当前的 MySQL 查看当前 MySQL 版本: ? 1 2 [root@coderknock ~]# mysql -V mysql Ver 14.14 D ...

  9. Python--基础之socket编程

    一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...

  10. QT blockingmaster例子学习

    dialog.h: #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include "masterthread.h&q ...