Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:66315 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 71737 invoked from network); 28 Feb 2013 07:19:27 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Feb 2013 07:19:27 -0000 Authentication-Results: pb1.pair.com header.from=petrich@tronic-media.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=petrich@tronic-media.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain tronic-media.com from 67.18.221.210 cause and error) X-PHP-List-Original-Sender: petrich@tronic-media.com X-Host-Fingerprint: 67.18.221.210 p44.net Received: from [67.18.221.210] ([67.18.221.210:33695] helo=mail.p44.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 58/00-05941-CF40F215 for ; Thu, 28 Feb 2013 02:19:26 -0500 Received: from rootp-server (p44net [127.0.0.1]) by mail.p44.net (Postfix) with ESMTP id 10BCD3A015C; Thu, 28 Feb 2013 08:10:10 +0100 (CET) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: "Terry Ellison" Cc: internals@lists.php.net References: <512B6110.6010901@ellisons.org.uk> Date: Thu, 28 Feb 2013 14:19:13 +0700 MIME-Version: 1.0 Content-Transfer-Encoding: Quoted-Printable Message-ID: In-Reply-To: <512B6110.6010901@ellisons.org.uk> User-Agent: Opera Mail/12.12 (Win32) Subject: Re: [PHP-DEV] (non)growing memory while creating anoymous functions via eval() From: petrich@tronic-media.com (=?utf-8?Q?Hans-J=C3=BCrgen_Petrich?=) Am 25.02.2013, 20:03 Uhr, schrieb Terry Ellison := > > 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-sto= p: >> = >> = >> for ( $fp =3D fopen('/dev/urandom', 'rb'); true;) { >> = >> eval ('$ano_fnc =3D function() {$x =3D "'.bin2hex(fread($fp,= >> mt_rand(1, 10000))).'";};'); >> = >> echo "Mem usage: ".memory_get_usage()."\n"; >> = >> } >> = >> = >> = >> But in this example not: >> = >> = >> for ( $fp =3D fopen('/dev/urandom', 'rb'); true;) { >> = >> eval ('$ano_fnc =3D function() {$x =3D "'.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=3D64291 which you might want to rev= iew > 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 wha= t > you want because if you think about the normal use of the anonymous= > function, say > > = > while (!feof($fp)) { > > $line =3D preg_replace_callback( > > '|

\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 th= e > 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 implici= t > assumption that the magic function name generated by the > = > eval ('$ano_fnc =3D 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 cr= eate_function() for a limited count... which will do the work also. Again thank you. Greetings Hans-J=C3=BCrgen