There is a custom exception class (which I have reduced to its minimum for this posting):
<?php
class MyException extends Exception {
public final function __set(String $member, $value) {
}
}
?>
__set()
is not used anywhere; in the original version it simply throws an Exception
and was introduced to prevent accidental writes to $e->nonexistingproperty
which is deprecated already and hopefully soon will be forbidden anyway.
And there is a code fragment (which is embedded in a much larger piece of software):
try {
var_dump(memory_get_usage());
echo "<br>";
$e = new MyException();
var_dump(memory_get_usage());
echo "<br>";
throw $e;
}
catch (Throwable) {
var_dump(memory_get_usage());
echo "<br>";
var_dump(get_class($e));
echo "<br>";
unset($e);
var_dump(memory_get_usage());
}
Running it I get the following output (the fragment starts with line 407 in the actual file):
contextlevel.php:408: int(3207080)
contextlevel.php:411: int(3216336)
contextlevel.php:416: int(3473200)
contextlevel.php:418: string(11) "MyException"
contextlevel.php:421: int(3463904)
Throwing (not creating!) the exception costs a lot of memory.
If I remove the (irrelevant __set
) throwing the exception still costs a lot of memory, but now it gets freed with unset($e)
. Why? (Look at the overall change of the memory footprint – just by removing an unused safety-guard method!)
contextlevel.php:408: int(2042552)
contextlevel.php:411: int(2051776)
contextlevel.php:416: int(2309016)
contextlevel.php:418: string(11) "MyException"
contextlevel.php:421: int(2057712)
I failed to reproduce this effect with a minimum working example, because the (jittering) numbers are too low then. Still this is 100% reproducible in my real-world software.
I can and will of course drop the __get()
and thus the problem I failed to properly describe yesterday should be solved. But still I would be interested why this happens. Any insights?