PHP memory unsetting array with objects

Go To StackoverFlow.com

1

Test One:

class Entity { }

$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
    $entities[] = new Entity();
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";

Output:

START: 631,664
BEFORE UNSET:44,404,904
AFTER UNSET: 8,954,568

Test Two:

class Entity { }

$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
    $entity = new Entity();
    $entities[] = &$entity;
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";

Output:

START: 631,664
BEFORE UNSET: 10,480,480
AFTER UNSET: 631,752

After i had trouble with memory limit, I played around with it a bit...

So after that i wonder how does garbage collection really work:

  1. Why does test one need more memory than test two?
  2. Why does php keep memory after unsetting the array in test one?

thx dave

2012-04-05 17:56
by user1315896


1

  1. The 1st one you are saving the actual object to each value in the array, and therefore when you unset the array, those objects are still somewhat there.
    • this is why this array takes up more memory -- it is storing actual objects
  2. The second one you are just saving the references to the objects (which are only in the scope of the for loop), and once those are unset, the objects are gone.
    • the reason why this array takes up less memory is that it is only storing references to objects.

So if you do what is here:

$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
    $entities[] = new Entity;
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
foreach($entities as &$entity) {
    unset($entity);
}
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";

And you unset each object in the array. You get the same results as your second try:

Example:

START: 3,237,720
BEFORE UNSET: 21,297,640
AFTER UNSET: 3,237,488

Demo: http://codepad.org/oUjzA46D

2012-04-05 17:59
by Neal
What do you mean by those objects are still somewhat there - webbiedave 2012-04-05 18:05
@webbiedave they are still somewhere in memory. Not out of scope just yet - Neal 2012-04-05 18:08
Your example doesnt really work: http://codepad.org/x3fTtry - user1315896 2012-04-05 18:52
@user1315896 what doesn't work about it - Neal 2012-04-05 18:52
I forgot to add the domo link: http://codepad.org/x3fTtry - user1315896 2012-04-05 18:56


1

Why does test one need more memory than test two?

PHP allocates more memory to store identifiers than it does for references (your first test assigns by identifier).

From the manual:

A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP 5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

This makes identifiers somewhat magical and they are specially handled.

Why does php keep memory after unsetting the array in test one?

unset merely marks a variable's memory for freeing by the GC's algorithm; it doesn't free the memory right then. When I run your first test, a significant amount of memory is freed (although not as much as your second test, likely due to the greater sizes being allocated).

2012-04-05 18:45
by webbiedave
Isn't this basically what my answer says - Neal 2012-04-05 18:54
No. Your answer it is storing actual objects is incorrect. Nor does your answer mention identifiers which are in no way actual objects (try $entity = new Entity(); $entities[] = $entity;). My answer also addresses his second question about why quite differently than yours - webbiedave 2012-04-05 18:59
what is the advantage of identifiers ? why does php use identifier instead of reference - user1315896 2012-04-05 19:28
Ads