samedi 20 août 2016

Workaround for PHP memory leak when using Reflection class in a loop

I have a loop like this

    foreach ($classes as $class)
    {
        $reflectionClass = new \ReflectionClass($class);
        ... //code that doesn't matter - commenting it out leaves the memory consumption all the same
    }

Which gives the Fatal error: Allowed memory size of 134217728 bytes exhausted result in case of a big number of classes to loop through and relatively small allowed memory size in php.ini (for me that's around 4000 classes and 128 MB memory setting).

Memory usage right before the loop start is around 1.6 MB.

As you might guess, leaving unset($reflectionClass) at the end of the loop body doesn't help at all.

Upon some googling my guess is that PHP doesn't free the memory taken by the object in case it has some internal references to other objects. Now, these posts (one, two, three) made me try using the garbage collector expicitly:

    gc_enable();
    foreach ($classes as $class)
    {
        $reflectionClass = new \ReflectionClass($class);
        ...
        unset($reflectionClass);
        gc_collect_cycles();
    }

Which still leads to the same result.

The solutions I see: 1) Increase allowed memory setting - which is ugly and sad. 2) Separate classes into portions and get the needed result from each portion separately via forking or executing some other PHP script - but this sounds like a tough way to go.

Is there a simple workaround for the memory leak? Am I missing something here?





Aucun commentaire:

Enregistrer un commentaire