On Fri, 2019-06-28 at 02:41 +0200, Benjamin Morel wrote:
> Hi internals,
> 
> I've tracked down a memory leak to an anonymous class created within
> eval():
> 
> ```
> for ($i = 0; $i < 1000000; $i++) {
>         $object = eval('return new class {};');
> 
>         if ($i % 1000 == 0) {
>                 echo memory_get_usage() . "\n";
>         }
> }
> 
> ```
> 
> The memory usage quickly ramps up and memory_limit is reached in
> seconds.
> Without eval(), the memory usage stays flat. I'm on 7.3.6.
> 
> *Is this a bug?* Or is this some inherent limitation of eval() that
> cannot
> be fixed?

I case this is non-trivial to fix. Each invocation recompile a new
piece of code, which creates a new class.

Similar to

    for ($i = 0; $i < 1000000; $i++) {
      eval("function f$i(){}");
    }
    f1();
    f2();
   ...

or

  for ($i = 0; $i < 1000000; $i++) {
        file_put_contents("c$i.php", 'return new class {};');
        $object = include "c$i.php";  
   }

Theoretical it is thinkable we could either detect equal classes (but
unlikely to happen ... if it's the same why do it in eval, zthus cost
likely is higher than benefit in most cases?) or unload the class once
it's not needed anymore (which is hard to detect with reflection and
other mechanisms which aren't bound to an instance's zval and also not
cheap)

johannes


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to