Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:65632 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 15912 invoked from network); 4 Feb 2013 12:11:38 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Feb 2013 12:11:37 -0000 Authentication-Results: pb1.pair.com smtp.mail=Terry@ellisons.org.uk; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=Terry@ellisons.org.uk; sender-id=unknown Received-SPF: error (pb1.pair.com: domain ellisons.org.uk from 79.170.44.47 cause and error) X-PHP-List-Original-Sender: Terry@ellisons.org.uk X-Host-Fingerprint: 79.170.44.47 mail47.extendcp.co.uk Received: from [79.170.44.47] ([79.170.44.47:40518] helo=mail47.extendcp.co.uk) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0A/B6-14611-875AF015 for ; Mon, 04 Feb 2013 07:11:37 -0500 Received: from host86-155-212-167.range86-155.btcentralplus.com ([86.155.212.167] helo=[192.168.1.91]) by mail47.extendcp.com with esmtpa (Exim 4.77) id 1U2KtY-0001Oa-1R; Mon, 04 Feb 2013 12:11:32 +0000 Message-ID: <510FA573.50502@ellisons.org.uk> Date: Mon, 04 Feb 2013 12:11:31 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: =?UTF-8?B?SGFucy1Kw7xyZ2VuIFBldHJpY2g=?= CC: internals@lists.php.net References: <510E9031.9040209@gmail.com> In-Reply-To: Content-Type: multipart/alternative; boundary="------------060005090700040601060604" X-Authenticated-As: Terry@ellisons.org.uk Subject: Re: [PHP-DEV] (non)growing memory while creating anoymous functions via eval() From: Terry@ellisons.org.uk (Terry Ellison) --------------060005090700040601060604 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit > Hi Terry and all > thank you very much for your response. > >> The only thing that confused me about what you say that the second >> *doesn't* grow > Yes, about that i was [and am still :-)] also confused... why the 2nd > one won't grow *non-stop* > >> so I checked and it does -- just the same as the first. > Right, it grows, but not non-stop as in the 1st one. > > The memory will stop growing (on my machine) at ~2491584 bytes and the > loop is able to run forever, > creating each eval() furthermore uniqe ano-function's but not > endless-filling Zend-internal tables. > >> but this still leaves the function record itself in the >> function_table hash so with a non-zero reference count and this >> doesn't get DTORed until request shutdown > Not familar with the Zend-internals but just about so i was imaging > and expecting it. > > That why i [still] also confused/wondering why in the 2nd example the > memory will not grow *endless*. > It seems that the function records in the function_table will be > DTORed (or similar cleaned up) before request-shutdown at some point... > > Could this be the case? > OK, Hans-Jürgen, this one has got me interested. I am developing a fork of APC optimized for cgi and cli use -- but that's a different topic -- though understanding the DTOR processes for compiler objects interests me because of this. I'll go through the code and especially for Closure objects to understand why. However thinking through this logically: 1. The fact that the second does stop growing means that that the reassignment of the global $ano sets the RC of the previous closure object to zero triggering DTOR of the lamba function. 2. There is something pathological about the first case which is frustrating garbage collection on the lambda function DTOR. I replaced your inner loop by: $len = $argv[1] & 1 ? $argv[2] : mt_rand(1, $argv[2]); $str = "'." . bin2hex(fread($fp, $len)) . "'"; if ($argv[1] & 2) $str = "function() {\$y = $str; };"; eval ("\$x = $str;"); echo "Mem usage: ".memory_get_usage()."\n"; to allow me to use arg1 to select one of the four test cases 0..3 and arg2 is the (max) string size, n say. This clearly shows the fact that the memory explosion only occurs if the string is allocated *inside* the lambda function. 4. If you substitute n<15 then memory growth rapidly stabilises for PHP 5.3.17 0, but still explodes for n>14 5. In the case of PHP 5.4.6 a similar effect occurs except that explosion occurs at n>11. 6. The fact that 5.3 and 5.4 are different is notable -- however, the fact that 5.4 is still (eventually) stable for n<12 means that this isn't a string interning issue. Interesting. Merits more research :-) --------------060005090700040601060604--