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 :-)

Reply via email to