Утечка памяти 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 делает это автоматически