清除PHP使用的内存

清除PHP使用的内存,php,memory,phpunit,Php,Memory,Phpunit,我遇到了一个有趣的问题。我使用的是PHPUnit,每次运行测试都会占用更多内存。即 2.25 MB 2.5 MB 3.0 MB 3.5 MB 有人知道如何清除正在消耗的记忆吗?有人能建议我深入探讨这一点吗?直接的问题是,我的一些较大的测试正在耗尽内存,而仅仅继续增加PHP中的最大内存分配是不够的……我需要知道为什么从命令行运行的PHPUnit测试在运行之间会有“停留”的内存使用,这是因为缺少重置功能 在测试时,我们必须确保测试环境是一致的,以便我们能够获得准确的结果。计算是输入/输出,因此我们

我遇到了一个有趣的问题。我使用的是PHPUnit,每次运行测试都会占用更多内存。即

2.25 MB

2.5 MB

3.0 MB

3.5 MB


有人知道如何清除正在消耗的记忆吗?有人能建议我深入探讨这一点吗?直接的问题是,我的一些较大的测试正在耗尽内存,而仅仅继续增加PHP中的最大内存分配是不够的……我需要知道为什么从命令行运行的PHPUnit测试在运行之间会有“停留”的内存使用,这是因为缺少重置功能

在测试时,我们必须确保测试环境是一致的,以便我们能够获得准确的结果。计算是输入/输出,因此我们应该使用它来重置存储,以防止像这样的“内存泄漏”。

如果您使用的是PDO(或类似的数据库抽象),那么您可以在使用DSN时使用“sqlite::memory:”。这有三大好处:

  • 每次测试后自动清除
  • 不会意外接触生产数据库(例如,即使在生产服务器上运行单元测试)
  • 都在内存中,因此测试可能运行得更快

  • 缺点是SQL必须在MySQL和SQLite之间可移植。这可能是相当多的工作(对于更大的项目来说,这通常是值得的,不仅仅是为了测试,而且是为了改进代码设计的方式。)在您的案例中,您在聊天记录中提到了使用原则,因此您可能已经有了一个很好的抽象,因此,它可能只在SQLite上运行而不做任何更改。

    内存增加有三到四个原因:

    1) PHPUnit收集代码覆盖率数据 对此,除了关闭代码覆盖之外,您无能为力

    2) PHPUnit缓存用于代码覆盖的文件令牌 您可以在phpunitxml中使用
    。请参阅中关于此的注释

    3) PHPUnit本身不能正确清理 在当前的实现中,它保留测试用例,因为结果数据存储在那里。在未来,这将被改变为更有效,但现在这是事情的运作方式

    4) 导致“4”:你也需要清理你自己 由于
    TestCase
    实例被保留,因此您的成员变量也被保留

    这意味着您可以通过使用

    public function tearDown() {
        unset($this->whatever);
    }
    
    但这样做非常乏味

    我的建议是为所有测试用例创建一个基本测试类,并使用以下方法:

    class MyBaseTest extends \PHPUnit_Framework_TestCase {
    
        protected function tearDown()
        {
            $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);
                }
            }
        }
    }
    
    这将以一种很好的、自动化的方式在您之后进行清理

    (片段的道具转到:)



    PHPUnit不能以向后兼容的方式完成这项工作,而不会破坏人们的项目,因此您必须自己添加它:)

    PHPUnit垃圾收集背后的技术细节已经被@edorian和@mauris涵盖,但我想添加PHPUnit(至少在我正在运行的版本3.7.21中)使您能够添加注释:

    /**
     * @backupGlobals disabled
     */
    class MyClassTests extends PHPUnit_Framework_TestCase{}
    

    在添加注释之前,每次运行测试套件时,我的内存使用量大约是原来的两倍,最后一次大约达到1100 MB。现在它们以15MB的速度运行

    您使用的是哪个版本的PHPUnit?您大致测试的是哪种代码?您是否正在向Travis CI推送测试?PHPUnit 3.7.8-13-ged6eed8,测试自定义框架。不把测试推给Travis CI.TBH:3.5MB不是很多。这些是单独的测试还是您使用一个PHP实例一个接一个地运行它们?我的一个测试在运行了大约10次之后,从消耗100MB变成了消耗500+MB。我从命令行运行一个单独的测试,如下所示:phpunit tests/unit/Models/mytest如果您使用这不仅对我不起作用;我大约40%的记忆都用光了。看起来它在
    $refl->getProperties()
    上爆炸了;也许它在测试中得到了过多的属性?