Утечка памяти Symfony и PhpUnit

у нас есть проблемы с утечкой памяти при загрузке доктрины в наших тестах phpunit

запуск документации Symfony : http://symfony.com/doc/2.7/cookbook/testing/doctrine.html мы написали этот тест:

use SymfonyBundleFrameworkBundleTestKernelTestCase;

class memoryleakTest extends KernelTestCase
{
    private $em;

    protected function setUp()
    {
        self::bootKernel();

        $this->em = static::$kernel->getContainer()
            ->get('doctrine')
            ->getManager();
    }

    protected function tearDown()
    {
        parent::tearDown();

        $this->em->close();
    }

    function testEEE1()  { 
    }
    function testEEE2()  { 
    }
    function testEEE3()  { 
    }
    function testEEE4()  { 
    }
    function testEEE5()  { 
    }
    function testEEE6()  { 
    }
    function testEEE7()  { 
    }
    function testEEE8()  { 
    }
    function testEEE9()  { 
    }
    function testEEE10()  { 
    }
    function testEEE11()  { 
    }
    function testEEE12()  { 
    }
    function testEEE13()  { 
    }
    function testEEE14()  { 
    }
    function testEEE15()  { 
    }
    function testEEE16()  { 
    }
}

мы получили этот результат (php_memory_usage между скобками):

testEEE1: . (42M)
testEEE2: . (42.7M)
testEEE3: . (43.3M)
testEEE4: . (44M)
testEEE5: . (44.8M)
testEEE6: . (45.5M)
testEEE7: . (46.1M)
testEEE8: . (46.8M)
testEEE9: . (47.4M)
testEEE10: . (48.1M)
testEEE11: . (48.7M)
testEEE12: . (49.4M)
testEEE13: . (50.1M)
testEEE14: . (50.7M)
testEEE15: . (51.4M)
testEEE16: . (52M)

если мы удалим загрузку doctrine manager в setup, мы получим (32,7 м) для каждого теста

это правильный способ разгрузить учение после каждого теста в функции teardown ?

3 ответов


полное решение, как оказалась здесь: https://github.com/symfony/symfony/issues/18236

для каждой службы, используемой в тесте phpunit, вы должны освободить ее, назначив null переменной, если вы хотите, чтобы сборщик мусора освободил память.

protected function tearDown()
{
    parent::tearDown();

    $this->em->close();

    $this->em=null;

    gc_collect_cycles();
}

чтобы сделать это еще проще для Вас, Вы можете иметь BaseTestCase.php с функцией teardown и поместите это внутрь:

// Remove properties defined during the test
    $refl = new \ReflectionObject($this);
    foreach ($refl->getProperties() as $prop) {
        if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
            $prop->setAccessible(true);
            $prop->setValue($this, null);
        }
    }

этот фрагмент кода избавит вас от некоторых головных болей:)


это не утечка памяти, просто нормальный поток, потому что вы загружаете ядро 16 раз.

просто попробуйте добавить gc_collect_cycles(); в своем tearDown() метод и вы увидите, что использование памяти уменьшилось. В качестве альтернативы вы можете установить memory_limit до 50 м, и вы увидите, что gc делает это автоматически