2

I'm curious about using of unset() language construct just about everywhere, where I took memory or declare some variables (regardless of structure).

I mean, when somebody declares variable, when should it really be left for GC, or be unset()?


Example 1:

<?php
$buffer = array(/* over 1000 elements  */);

// 1) some long code, that uses $buffer

// 2) some long code, that does not use $buffer
?>
  1. Is there any chance, that $buffer might affect performance of point 2?
  2. Am I really need (or should) to do unset($buffer) before entering point 2?

Example 2:

<?php
function someFunc(/* some args */){
    $buffer = new VeryLargeObject();

    // 1) some actions with $buffer methods and properties

    // 2) some actions without usage of $buffer

    return $something;
}
?>
  1. Am I really need (or should) to do unset($buffer) within someFunc()s body before entering point 2?
  2. Will GC free all allocated memory (references and objects included) within someFunc()s scope, when function will come to an end or will find return statement?

I'm interested in technical explaination, but code style suggestions are welcome too.

Thanks.

BlitZ
  • 12,038
  • 3
  • 49
  • 68
  • There is nothing wrong with unset any variable when you are done with it, but with large object like that I would say definitely. I'm sure the code running in part 2 would enjoy the extra room. – Orangepill May 15 '13 at 05:10
  • @Orangepill I'm think so too, but some programmers (on my job place) think, that there is no need to do it, because "PHP has GC!!". For example, a lot of Symfony core objects are LARGE, but they are existing within methods. Should they be unset, when they done, instead of waiting for a function end? Also, they refered to "`php_memory_limit` is big enough" to ignore `unset()`, PHP will do it anyway". – BlitZ May 15 '13 at 05:17
  • 1
    `unset` will free memory [only when the object (not variable) is no longer referenced](http://www.php.net/manual/en/function.unset.php#84911). And GC will [_very slightly_ decrease performance](http://www.php.net/manual/en/features.gc.performance-considerations.php). But in general, there is nothing wrong unsetting a no-longer-used variable. – Passerby May 15 '13 at 05:25
  • @Passerby Thanks, I will consider it in my further coding. – BlitZ May 16 '13 at 02:36

1 Answers1

1

In php, all memory gets cleaned up after script is finished, and most of the time it's enough.

From php.net:

unset() does just what it's name says - unset a variable. It does not force immediate memory freeing. PHP's garbage collector will do it when it see fits - by intention as soon, as those CPU cycles aren't needed anyway, or as late as before the script would run out of memory, whatever occurs first.

If you are doing $whatever = null; then you are rewriting variable's data. You might get memory freed / shrunk faster, but it may steal CPU cycles from the code that truly needs them sooner, resulting in a longer overall execution time.

In reality you would use unset() for cleaning memory pretty rare, and it's described good in this post: https://stackoverflow.com/a/2617786/1870446

By doing an unset() on a variable, you mark the variable for being "garbage collected" so the memory isn't immediately available. The variable does not have the data anymore, but the stack remains at the larger size.
In PHP >= 5.3.0, you can call gc_collect_cycles() to force a GC pass. (after doing gc_enable() first).
But you must understand that PHP is script language, it's not Java so you shouldn't consider it like one. If your script is really that heavy to use tons of RAM - you can use unset and when script is close to exceed the memory - GC will trigger and clean up everything useless, including your unset variables. But in most cases you can forget about it.
Also, if you would want to go for unsetting every variable you do not use - don't. It will actually make your script execute longer - by using more CPU cycles - for the sake of getting free memory that would, in most cases, would never be needed.
Some people also say that they use unset to explicitly show that they won't use variable anymore. I find it a bad practice too, for me it just makes code more verbose with all these useless unsets.

Community
  • 1
  • 1
konnigun
  • 1,797
  • 2
  • 17
  • 30
  • You mean, `unset()` does not trigger `GC` at all? – BlitZ May 15 '13 at 05:29
  • Just read updated answer. Clear, but I need more opinions. Currently, I'll accept it, if no other sufficient answers will be provided in near future. Thanks. – BlitZ May 15 '13 at 06:02