views:

86

answers:

5

Hi,

I have two simple questions. What is better/useful for memory cleanup.

$var = null;

or

unset($var);

I have one function with one cycle. I am getting (after few minutes)

Fatal error: Allowed memory size of 419430400 bytes exhausted

I am setting null and unset()-ing every object (at the end of the cycle) but still without any success :( I cant find out what is consuming memory.

And what about function calls in cycle? Will PHP release all allocations in these functions?(after call)

A: 

And what about function calls in cycle? Will PHP release all allocations in these functions?(after call)

Once the execution leaves the scope of a function, all non-static variables are removed from memory.

Mchl
Thanks, but question is when?immediately after call ?
Michal Drozd
I am asking you becouse I know PHP is stupid in this area. In other languages this is matter of course.
Michal Drozd
As soon as possible. I don't want to say 'immediately' because that might not be exactly true (especially if we're dealing with resources)
Mchl
+3  A: 

PHP itself confuses both concepts sometimes but, in general, a variable set to NULL is not the same as a variable that does not exist:

<?php

$foo = 'One';
$bar = 'Two';

$foo = NULL;
unset($bar);

var_dump($foo); // NULL
var_dump($bar); // Notice: Undefined variable: bar
var_dump(get_defined_vars()); // Only foo shows up: ["foo"]=> NULL

?>
Álvaro G. Vicario
This confusion can mostly be attributed to the false assumption that `isset` is the counterpart of unset. Unset deletes a variable symbol from the current scope, where as isset also checks if it exists AND non-`null`. For example, `isset($foo)` and `isset($bar)` would both return false in the above example.
Denis 'Alpheus' Čahuk
Also, I'd avoid putting the closing `?>` delimiter into code blocks on SO. Makes code needlessly (**slightly**) harder to read.
Denis 'Alpheus' Čahuk
Apart from that confusion, it's actually very hard to distinguish between NULL and unset. Seriously: http://stackoverflow.com/questions/2283647/test-for-null-value-in-a-variable-that-may-not-be-set
Álvaro G. Vicario
+1  A: 

unset() does just that, it unsets a variable; but it does not immediate free up memory.

PHP's garbage collector will actually free up memory previously used by variables that are now unset, but only when it runs. This could be sooner, when CPU cycles aren't actively being used for other work, or before the script would otherwise run out of memory... whichever situation occurs first.

And be aware that unset won't necessarily release the memory used by a variable if you have other references to that variable. It will simply delete the reference, and reduce the reference count for the actual stored data by 1.

EDIT While unset doesn't immediately release the memory used (only garbage collection actually does that) the memory that is no longer used as a result is available for the declaration of new variables

Mark Baker
Thanks, but when it will be released ? I attached my code snippet. When I run it start, after first 5 minutes I am getting fatal error 400 MB exhausted..
Michal Drozd
This is all wrong. `unset` does free the memory in the same sense as the garbage collector (which btw exists only since PHP 5.3) does, i.e., they return the blocks to the memory allocator if the underlying storage of the variable has no more references.
Artefacto
unset() makes the memory used by the variable available for reuse (by decrementing the zval refcount), but doesn't deallocate it. The Zend engine knows that memory block is available for reuse when the zval refcount is zero. Garbage collection actually deallocates the memory, effectively making a C free() call. At least that was my understanding. Though I confess that understanding is based on a myriad of conflicting sources
Mark Baker
@Mark Baker : you are correct. The only change they made in PHP 5.3 was that the garbage collector now (presumably) can handle circular references (which doesn't work in PHP 5.2 or lower, hence you could run out of memory soon since objects were never actually freed if you had circular references).
wimvds
+1  A: 

If you unset the variable it is just marked, so on the next garbage collection it will be removed. If setting to null, the data of the variable gets overwritten.

Maybe see also the comments on the php manual: Unset Manual

At least this behaviour is also what i have encountered so far. But to fix it, you should first try to find out what is causing the memory to grow. The memory_get_usage function should be helpful for this.

TheCandyMan666
A: 

I found problem.

First it was caused by xdebug profilling tools (i have turned on everything :) ) - and it consume lot of memory.

So remember: xdebug (when profilling turned on) consumes some memory in PHP process of your application

Second, I didn't release static members used in called functions.

Michal Drozd