PHP memory usage after flushing arrays?

I run the code below without dropping arrays and then dropping arrays using PHP

disarmed ($ array here)

And the amount of memory increases when I use unset. Any ideas why? And even better, what is the right way to free up memory?

NOTICE: PLEASE, there is no sermon on preliminary optimization, its EVIL and all that is a test, so don’t give lectures about it and thank you.

//show current memory usage BEFORE echo memory_get_usage() . "\n"; // 57960 //start timer $start3 = microtime(true); // arrays for header menu selector $header_home = array('home' => true); $header_users = array('users.online' => true, 'users.location' => true, 'users.featured' => true, 'users.new' => true, 'users.browse' => true, 'users.search' => true, 'users.staff' => true); $header_forum = array('forum' => true); $header_more = array('widgets' => true, 'news' => true, 'promote' => true, 'development' => true, 'bookmarks' => true, 'about' => true); $header_money = array('account.money' => true, 'account.store' => true, 'account.lottery' => true, 'users.top.money' => true); $header_account = array('account' => true); $header_mail = array('mail.inbox' => true, 'mail.sentbox' => true, 'mail.trash' => true, 'bulletins.post' => true, 'bulletins.my' => true, 'bulletins' => true); //run throught 1,000 iterations for($i = 0; $i < $iterations; ++$i) { if(isset($header_home[$p])) $current_home = 'current'; else if(isset($header_users[$p])) $current_users = 'current'; else if(isset($header_forum[$p])) $current_forum = 'current'; else if(isset($header_more[$p])) $current_more = 'current'; else if(isset($header_money[$p])) $current_money = 'current'; else if(isset($header_account[$p])) $current_account = 'current'; else if(isset($header_mail[$p])) $current_mail = 'current'; } //unset the arrays unset($header_money); unset($current_home); unset($current_users); unset($current_forum); unset($current_more); unset($current_account); unset($current_mail); //show time $end3 = microtime(true); echo number_format($end3 - $start3, 7) . ' Time3 ARRAY<br />'; //show current memory usage AFTER echo memory_get_usage() . "\n"; 
+4
source share
4 answers

I did a very quick test by doing the following:

  • Declaration $iterations = 10; at the beginning of the script
  • using $p , not $i in a for loop (you use $p to access the elements of the array, not $i )
  • adding a line to display used memory before unsets

I get this using PHP 5.3.1 (today is a snapshot):

 328616 332176 331728 

Three outputs:

  • first: start of a script (one that says: "Show current memory usage BEFORE")
  • second: the one that I added before the calls to cancel; immediately after the for loop ends
  • third: the one you put at the end of your script.

Thus, unsets really provoke the release of some memory, rather than increasing the memory used; -)

But only a relatively small fraction of the allocated memory is freed ...


Now the question may be, “what causes some memory to be used and not freed, an event if I call unset on arrays” - in fact, maybe this is what you meant for the first time?

Well, I suppose that disabling the arrays themselves does not make PHP free the memory allocated for elements inside the arrays ...

Similarly, this note on the uninstalled manual page says (quoted):

unset () does what it calls - disable the variable. This does not immediately release memory. The PHP garbage collector will do this when it sees seizures - at will, as soon as these processor cycles are not needed anyway, or even before the script runs out of memory, whatever the first happens.

If you do $ whatever = null; then you rewrite the variable data. You can free memory / shrink faster, but can steal the loop processor from the code that you really need them earlier, resulting in a total runtime.

And, in fact, this may seem interesting; -)

However, running a few quick tests does not cause anything interesting; I believe my script / data is not large enough to force PHP to free up unused memory or something like that ...


Note: if I use gc_collect_cycles (PHP> = 5.3) to force garbage collection after unsets, it doesn’t change anything - - I suppose this is because there is no "lost cycle".


* BTW: running your code gave me some comments (e.g. $ p vs $ i); Are you developing with setting error_reporting to send notifications? *

+10
source

You first call memory_get_usage() before arrays exist. You must do this between creations + filling in your arrays and << 21>

Here you see that more memory is used at the end of the script than at the beginning.

+3
source

unset() not a garbage collection mechanism.

Thus, calling unset() does not mean that the memory stored by the variable is instantly available, it simply means that the variable is scheduled for garbage collection. The PHP engine does this on its schedule.

+1
source

I do not know if this matters, but you have not canceled $start3 , $end3 and all other $home_xxx arrays than $home_money .

In addition, I would advise keeping the test simpler. For example, using only one array.

Keep it simple. This will make your test / test more meaningful.

EDIT

Just played with him a bit.

First test

 <?php $array = array(); echo "START:". memory_get_usage() . "\n"; for ( $i = 0; $i<1000; $i++ ) { $array[] = 'foo'; } echo "BEFORE UNSET: " . memory_get_usage() . "\n"; unset($array); echo "AFTER UNSET: " . memory_get_usage() . "\n"; sleep(120); echo "AFTER A WHILE: " . memory_get_usage() . "\n"; 

Output:

 START:53632 BEFORE UNSET: 146360 AFTER UNSET: 118848 AFTER A WHILE: 118848 

Second test :

 <?php $array = array(); echo "START:". memory_get_usage() . "\n"; for ( $i = 0; $i<1000; $i++ ) { $array[] = 'foo'; } echo "BEFORE UNSET: " . memory_get_usage() . "\n"; for ( $i = 0; $i<count($array); $i++ ) { unset($array[$i]); } unset($array); echo "AFTER UNSET: " . memory_get_usage() . "\n"; 

Output:

 START:53944 BEFORE UNSET: 146680 AFTER UNSET: 119128 

Thus, a theory that only cancels graphics for garbage collection does not work (at least not in PHP 5.2.8, but then they changed a lot in GC PHP 5.3).

I am afraid that there is not much that you can do than cancel: - (

+1
source

All Articles