Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling unset() in PHP script

Tags:

php

Coming from a C/C++ background, I am used to doing my own garbage collection - i.e. freeing resources after using them (i.e. RAII in C++ land).

I find myself unsetting (mostly ORM) variables after using them. Are there any benefits of this habit?

I remeber reading somewhere a while back, that unsetting variables marks them for deletion for the attention of PHP's GC - which can help resource usage on the server side - true or false?

[Edit]

I forgot to mention, I am using PHP 5.3, and also most of the unset() calls I make are in a loop where I am processing several 'heavy' ORM variables

like image 255
morpheous Avatar asked Aug 06 '10 16:08

morpheous


2 Answers

I find that if your having to unset use alot your probably doing it wrong. Let scoping doing the "unsetting" for you. Consider the two examples:

1:

$var1 = f( ... );
....
unset( $var1 );

$var2 = g( ... );
....
unset( $var2 );

2:

function scope1()
{
     $var1 = f( ... );
     ....
} //end of function triggers release of $var1

function scope2()
{
     $var2 = g( ... );
     ....
} //end of function triggers release of $var2

scope1();
scope2();

The second example I would be preferable because it clearly defines the scope and decreases the risk of leaking variables to global scope (which are only released at the end of the script).

EDIT:

Another things to keep in mind is the unset in PHP costs more (CPU) than normal scope garbage collection. While the difference is small, it goes to show how little of an emphases the PHP team puts on unset. If anything unset should give PHP insight that on how to release memory, but it actually adds to execution time. unset is really only a hack to free up variables that are no longer needed, unless your doing something fairly complex, reusing variables (which acts like a natural unset on the old variable) and scoping should be all you ever need.

function noop( $value ){}

function test1()
{
    $value = "something";
    noop( $value ); //make sure $value isn't optimized out
}

function test2()
{
    $value = "something";
    noop( $value ); //make sure $value isn't optimized out
    unset( $value );
}

$start1 = microtime(true);
for( $i = 0; $i < 1000000; $i++ ) test1();
$end1 = microtime(true);

$start2 = microtime(true);
for( $i = 0; $i < 1000000; $i++ ) test2();
$end2 = microtime(true);

echo "test1 ".($end1 - $start1)."\n"; //test1 0.404934883118
echo "test2 ".($end2 - $start2)."\n"; //test2 0.434437990189
like image 161
Kendall Hopkins Avatar answered Oct 27 '22 14:10

Kendall Hopkins


If a very large object is used early in a long script, and there is no opportunity for the object to go out of scope, then unset() might help with memory usage. In most cases, objects go out of scope and they're marked for GC automatically.

like image 45
Ryan Tenney Avatar answered Oct 27 '22 12:10

Ryan Tenney