Am 25.02.2013, 20:03 Uhr, schrieb Terry Ellison <te...@ellisons.org.uk>:
On 03/02/13 15:27, Hans-Juergen Petrich
wrote:
In this
example (using php-5.4.11 on Linux) the memory will grow non-stop:
for ( $fp = fopen('/dev/urandom', 'rb'); true;) {
eval ('$ano_fnc = function() {$x = "'.bin2hex(fread($fp,
mt_rand(1, 10000))).'";};');
echo "Mem usage: ".memory_get_usage()."\n";
}
But in this example not:
for ( $fp = fopen('/dev/urandom', 'rb'); true;) {
eval ('$ano_fnc = function() {$x = "'.bin2hex(fread($fp,
10000)).'";};');
echo "Mem usage: ".memory_get_usage()."\n";
}
Hans-Juergen, I've raised a bugrep
https://bugs.php.net/bug.php?id=64291 which you might want to review
and add any appropriate comments. I had to think about this one. It's
worthwhile observing that this second example is the only
occasion, as far as I know, that PHP does any garbage collection of
code objects before request shutdown. For example create_function()
objects are given the name "\0LambdaN" where N is the count of the
number of created functions so far in this request. They are
registered in the function table and persist until request
shutdown. That's the way PHP handles them by design.
As I said in the bugrep, the normal behaviour of persistence is what
you want because if you think about the normal use of the anonymous
function, say
while (!feof($fp)) {
$line = preg_replace_callback(
'|<p>\s*\w|',
function($matches) {return strtolower($matches[0]);},
gets($fp)
);
echo $line;
}
Then the anonymous function is compiled once and rebound to the
closure object which is passed as the
second argument for the callback each time through the loop. OK,
doing the closure CTOR/DTOR once per loop. is not the cleverest of
ideas and this is the sort of thing that would be hoisted out of the
loop in a language which did such optimization, but PHP doesn't. It's a
LOT better that compiling a new function each loop (which is
how Example #1 on
http://php.net/manual/en/function.preg-replace-callback.php does
it!) This is what you want to happen.
It's just too complicated for PHP to work out if the function might
or not be rebound to. I suspect the bug here is really the implicit
assumption that the magic function name generated by the
eval ('$ano_fnc = function() { ... }');
is unique, but as your examples shows, thanks to garbage collection
and reuse of memory, sometimes it isn't. In these circumstances
thank to the use of a hash update and the table DTOR the old one is
deleted.
So assume that what you are doing is exploiting a bug, so my advice
is not to do this. It might be fixed in a future release.
Regards Terry
Thank you Terry for this information. Yes, i avoid using it. I'll use
create_function() for a limited count... which will do the work also.
Again thank you.
Greetings
Hans-Jürgen
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php