Symfony和PhpUnit内存泄漏

时间:2016-03-16 09:55:14

标签: symfony doctrine phpunit

在我们的phpunit测试中加载Doctrine时,我们遇到内存泄漏问题

开始使用Symfony的文档: http://symfony.com/doc/2.7/cookbook/testing/doctrine.html我们写了这个测试:

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

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)

如果我们删除了在设置中加载的学说管理器,我们得到(32,7M)每个测试

在拆解功能的每次测试后卸载学说是否正确?

3 个答案:

答案 0 :(得分:5)

此处找到的完整解决方案: https://github.com/symfony/symfony/issues/18236

对于phpunit测试中使用的每个服务,如果希望垃圾收集器释放内存,则必须通过为变量赋值null来释放它。

select *
from Users U
outer apply (
        select Cnt = count(*) from  Customers 
        where ManagerID = U.UserID ) res
where U.UserID between  1574 and 1580

答案 1 :(得分:4)

为了让您更轻松,您可以使用具有拆卸功能的BaseTestCase.php并将其放入:

// 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);
        }
    }

这段代码可以让您免于一些麻烦:)

答案 2 :(得分:0)

这不是内存泄漏,只是正常流程,因为你启动内核16次。

尝试在gc_collect_cycles();方法中添加tearDown(),您会看到内存使用率下降。 或者,您可以将memory_limit设置为50M,您将看到gc自动运行