入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

PHP中的unset方法究竟能否释放内存

创建时间:2015-10-23 投稿人: 浏览次数:151

博客搬家:http://chanyaw.cn


有的人说PHP的unset并不真正释放内存, 有的说, PHP的unset只是在释放大变量(大量字符串, 大数组)的时候才会真正free内存, 更有人说, 在PHP层面讨论内存是没有意义的.

也有人说:

unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。
只有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存。

那是不是这样呢,我们先来看下面的例子:

$s=str_repeat("1",255); //产生由255个1组成的字符串 
$m=memory_get_usage(); //获取当前占用内存 
unset($s); 
$mm=memory_get_usage(); //unset()后再查看当前占用内存 
echo $m-$mm;

windows php5.5 输出264,当上例中$s=str_repeat("1", 256);时 输出273,这就说明 php5.5版本的unset释放内存,并没有256字节的限制。

我们再来看下面的例子:

$s=str_repeat("1",256); //这和第二个例子完全相同 
$p=&$s; 
$m=memory_get_usage(); 
unset($s); //销毁$s 
$mm=memory_get_usage(); 
echo $p."<br />"; 
echo $m-$mm; 

window php5.5 输出256个1,第二行 -48. 可见及时销毁了变量$s,不销毁$p 时并没有释放掉内存。

而当在 unset($s) 下加上 unset($p) 时候,输出 320 ,证明内存被释放了,也就是说 只有当指向变量的所有引用 ,都被销毁时候 才会真正释放内存。

为了打破砂锅问到底,我们从php的变量内存分配说起:

首先我们要知道php的内存分配是隐式的,并不像c语言那样显示调用内存分配API就会分配内存。

比如我们 定义变量:$i = "How are you!";

隐式分配有两个过程:1.为变量分配内存,存入符号表。2 .为变量值分配内存。

让我们来了解下,php变量究竟是如何表示的呢?

PHP是一个弱类型,动态的脚本语言。所谓弱类型,就是说PHP并不严格验证变量类型(严格来讲,PHP是一个中强类型语言,这部分内容会在以后的文章中叙述),在申明一个变量的时候,并不需要显示指明它保存的数据的类型:

$var = 1; //int
  $var = "laruence"; //string
  $var = 1.0002; //float
  $var = array(); // array
  $var = new Exception("error"); //object;
动态语言,就是说,PHP的语言结构在运行期是可以改变的,比如我们在运行期require一个函数定义文件,从而导致语言的函数表动态的改变。
所谓脚本语言,就是说,PHP并不是独立运行的,要运行PHP我们需要PHP解析器。PHP的执行是通过Zend engine(ZE, Zend引擎), ZE是用C编写的,大家都知道C是一个强类型语言,也就是说,在C中所有的变量在它被声明到最终销毁,都只能保存一种类型的数据。 那么PHP是如何在ZE的基础上实现弱类型的呢?

在PHP中,所有的变量都是用一个结构-zval来保存的, 在Zend/zend.h中我们可以看到zval的定义:

typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount;
    zend_uchar type;
    zend_uchar is_ref;
  } zval;

其中zvalue_value是真正保存数据的关键部分,现在到了揭晓谜底的时候了,PHP是如何在ZE的基础上实现弱类型的呢? 因为zvalue_value是个联合体(union),

typedef union _zvalue_value {
    long lval;
    double dval;
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;
那么这个结构是如何储存PHP中的多种类型的呢?
PHP中常见的变量类型有:

1. 整型/浮点/长整型/bool值 等等
2. 字符串
3. 数组/关联数组
4. 对象
5. 资源
PHP根据zval中的type字段来储存一个变量的真正类型,然后根据type来选择如何获取zvalue_value的值,比如对于整型和bool值:
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。