43

There is a way to get the total memory PHP is using (memory_get_usage()) but how does one get the size in memory of an individual object?

I'm obviously not talking about count() as I want the number of bytes in a potentially complex data structure.

5 Answers 5

24

You can call memory_get_usage() before and after allocating your class as illustrated in this example from IBM. You could even create a wrapper to do this, possibly storing the result on a member variable of the complex class itself.

EDIT:

To clarify the part about storing the allocated memory size, you can do something like this:

class MyBigClass
{
    var $allocatedSize;
    var $allMyOtherStuff;
}

function AllocateMyBigClass()
{
    $before = memory_get_usage();
    $ret = new MyBigClass;
    $after = memory_get_usage();
    $ret->allocatedSize = ($after - $before);

    return $ret;
}

At any point in the future, you could check allocatedSize to see how big that object was at time of allocation. If you add to it after allocating it, though, allocatedSize would no longer be accurate.

Sign up to request clarification or add additional context in comments.

5 Comments

What if PHP decides to free the memory that was kept allocated, just at the "wrong time" ? I don't really know when PHP frees memory (kind of "when needed", I suppose), but I'm guessing this freeing could bring some problems ? Especially with the garbage collector introduced by PHP 5.3 for cyclic-references ?
Well yeah, but in addition to what Pascal mentioned, I want to be able to find this out at different times, not just at allocation time. I want to find this out many lines down the road.
@Pascal: PHP will not free memory that's still referenced by an object actively being used. Cyclic references means A references B and B references A, but nothing else references either A or B. So memory will not be freed as long as the program can still reference it in any way.
@Artem: I mentioned in my post that you could keep the allocated size as part of your data structure. I'll edit the post now to make that clearer.
Is not reliable. Have tested with simpleXML and printing memory before and after load + tested with memory_get_peak_usage on xml-files of several megabytes (on php 5.5).
20

Would it not make sense to try serializing the object and reading the string length? Obviously it will be several bytes off because serialized string would have s:'string' therefore s:'' being extra bytes... unless serialize could be the same way that PHP stores objects???

so for example

$size = strlen(serialize($object));

Just a thought?

Another messy but possibly accurate thought:

Assuming a class instance variable that has been manipulated a few times since instantiation:

$DB; // database access class for eg.
$mem = memory_get_usage();
$DB_tmp = clone $DB;
$mem = memory_get_usage() - $mem;
unset($DB_tmp);

$mem could be the exact amount of memory allocated to $DB;

1 Comment

clone isn't working for me (I don't know why). It always reports 100 bytes after cloning an object.
3

I don't think this is quite possible ; I've never seen anything that would allow you to get the size of an object in memory.

A solution to get a pretty rough idea might be to kind of serialize your data, and use strlen on that... But that will really be something of an estimation... I wouldn't quite rely on anything like that, actually...


Even debug_zval_dump doesn't do that : it ouput the data in a variable and the refcount, but not the memory used :

$obj = new stdClass();
$obj->a = 152;
$obj->b = 'test';

echo '<pre>';
debug_zval_dump($obj);
echo '</pre>';

will only get you :

object(stdClass)#1 (2) refcount(2){
  ["a"]=>
  long(152) refcount(1)
  ["b"]=>
  string(4) "test" refcount(1)
}

1 Comment

Very interesting. My next question was actually about getting refcounts to figure out why there is a memory leak. Thanks!
1

Since clone (from Prof83's answer) didn't work for me, I tried to serialize and unserialize the variable whose size I want to measure:

function getMemoryUsage($var) {
    $mem = memory_get_usage();
    $tmp = unserialize(serialize($var));
    // Return the unserialized memory usage
    return memory_get_usage() - $mem;
}

I think it reports better results, at least for me.

2 Comments

you did not use $tmp variable
on the last line, memory_get_usage is now equal to $mem plus the size of $tmp. The variable itself may not be used but it is required.
-10

If you just want to know the size of object, and not for your next code, return it to the browser, and you can see how much the network transmit the object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.