前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己用的变量,请自己清理干净

自己用的变量,请自己清理干净

作者头像
写PHP的老王
发布2019-08-12 15:25:10
4710
发布2019-08-12 15:25:10
举报
文章被收录于专栏:写PHP的老王写PHP的老王

码代码真的不是搬砖那么简单。一个变量虽然都能实现功能,但是不同的选择会有不同的影响。自己用的变量,请自己清理干净!php中的内存扩充是以两倍的方式扩充,同时在变量的发生改变才去改变引用。

  • 数组变量。

创建一个空数组,对这个数组插入100个元素,然后再把这100个元素从数组中删除,php占用的内存有什么变化?

代码语言:javascript
复制
    $m = memory_get_usage();
    $i = 100;
    for($j=0;$j<$i;$j++){
        $data[] = $j;
    }

    $m1 = memory_get_usage();
    for(;$j>0;$j--){
        unset($data[$j-1]);
    }
    $m2 = memory_get_usage();
    unset($data);
    $m3 = memory_get_usage();
    var_dump($m,$m1,$m2,$m3);

以上输出内容

代码语言:javascript
复制
int(357432)
int(386184)
int(386184)
int(357464)

可以看出,当数组的数据插入之后再弹出,并没有释放内存空间,只有当真正unset之后(或者重新赋值)才会释放掉。 在循环体中插入一下代码

代码语言:javascript
复制
if($current!=memory_get_usage())
{
    $current = memory_get_usage();
    var_dump($current,$j);
}

输出内容:

代码语言:javascript
复制
int(357704)
int(0)
int(357736)
int(1)
int(357960)
int(8)
int(358408)
int(16)
int(359304)
int(32)
int(361608)
int(64)
int(365704)
int(128)
int(373896)
int(256)
int(386184)
int(512)

可以看到,不是每次插入都会引起内存变化,因为php每次内存扩充都是以倍数的方式扩充。因此数组的使用不是那么随便。数组每个元素的占用内存大小,一个临界的点就可以导致内存翻倍。对于数组,循环前先置空,谁知道前面有没有人用这个名。不使用请主动清理。

  • 对象变量,静态变量 对象变量,有其自身的生命周期。当对象变量析构,所占用的内存会被释放掉。对象内部都是随着对象本身的消亡而消亡。
代码语言:javascript
复制
class Test{
    public $num = 1;
    public function testnum(){
        return $this->num;
    }
}


$m = memory_get_usage();
$test = new Test();
$m1 = memory_get_usage();
$test->testnum();
$m2 = memory_get_usage();
$test1 = clone $test;
$test1->num = 2;
$m3 = memory_get_usage();
$test1 = null;
$m4 = memory_get_usage();
var_dump($m,$m1,$m2,$m3,$m4);

输出内容

代码语言:javascript
复制
int(356768)
int(356808)
int(356808)
int(356848)
int(356808)

对象等号赋值,指向相同的引用地址,内存不会变化太多。clone这是创建一个全新的对象,占用内存如图new一个新对象一样。当对象unset或赋值空的时候,对象占用内存被释放。

在一些框架中,经常会看到一个静态对象更加特定的参数创建对象,看一下这种情况内存如何

代码语言:javascript
复制
class TestMe{
    public static $factorys = [];
    public static function getTestor($name){
        if(isset(self::$factorys[$name]))
        {
            return self::$factorys[$name];
        }
        switch($name){
            case 'Test':
                self::$factorys[$name] = new Test();
        }
        return self::$factorys[$name];
    }
}
$m = memory_get_usage();
$test = TestMe::getTestor('Test');
$m1 = memory_get_usage();
$test = null;
$m2 = memory_get_usage();
var_dump($m,$m1,$m2);

输出内容:

代码语言:javascript
复制
int(356360)
int(356624)
int(356624)

因为静态变量TestMe中还有一份引用test对象,因此当test置为null的时候,内存并没减少,只有当将所有的对象引用释放,内存才能够释放。但是对于类静态属性,如果没有主动释放,只有当进程结束才会释放。 因此对于类的静态属性,没有析构方法为你兜底,请主动显示的释放掉资源。

对于变量的使用,不管什么类型,使用完之后,请记得做清理工作,特别是在静态变量中。php数组是高效的,但是也是吃内存的家伙。可以参考文章PHP数组到底占用多少内存空间。对于php web应用而言,出现内存问题的可能性不大,问题也不容易显现,因为每次请求之后,所占用的资源就被释放掉了。但是目前php常驻内存的应用逐渐广泛,内存的问题就变得尤为明显。当一个程序连续不断的跑,每次处理请求都会有1k内存的增加,那么1024就能产生1M内存的增加。时间久了,就容易造成系统资源不足,进程被系统强制kill。自己用的东西,自己得清理干净。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写PHP的老王 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档