学说冲洗会改变并释放内存



我正在遇到在具有较低内存限制的Symfony项目上工作的问题。我需要创建多个实体,将它们添加到另一个实体(实体是关联的(,然后将其刷新到数据库中。这发生在while循环中。

问题在于,有时循环无法完成整个周期,因为该过程崩溃了记忆耗尽。当然我无法提高内存限制。

我尝试通过一些代码更好地解释您...

实体结构

class Device
{
    /**
     * @ORMManyToMany(targetEntity="Resource", inversedBy="devices",cascade={"persist", "refresh"}, fetch="EXTRA_LAZY")
     */
    protected $resources;
    public function addResource(Resource $resource)
    {
        if ($this->resources->contains($resource)) return;
        $this->resources->add($resource);
        $resource->addDevice($this);
    }
}
class Resource
{
    /**
     * @ORMManyToMany(targetEntity="Device", mappedBy="resources")
     */
    protected $devices;
    public function addDevice(Device $device)
    {
        if ($this->devices->contains($device)) return;
        $this->devices->add($device);
        $device->addResource($this);
    }
}

循环

function doIt(Device $device) {
    while(...) {
        $res = new Resource(...);
        $device->addResource($res); // store $res in memory until end
    }
    $em->persist($device);
    $em->flush();
}

因此,问题是在循环完成之前,$device保持内存Resource对象,有时达到内存限制。

我到目前为止尝试的

function doIt(Device $device) {
   $i = 0;
   while(...) {
       $res = new Resource(...);
       $device->addResource($res);
       $i++;
       if ($i % 100 == 0) {
              $em->persist($device);
              $em->flush($device);
              $device->setResources(null); // free up Resources in memory
              $em->refresh($device); // Resources are not stored in memory
       }
   }
   $em->persist($device);
   $em->flush();
}

这也不是很好,因为我无论如何都会看到记忆的提升(可能是由学说引起的(。此外

您会做什么?

您可以尝试改善情况:

禁用导入的设置阶段中的理论SQL记录机构

$this->getContainer()->get('doctrine')->getConnection()->getConfiguration()->setSQLLogger(null);

尝试定期调用一个清晰的调用(我在处理并冲洗一批项目后要做(,但以前阅读文档,因为可能会根据您的代码有副作用

$this->entityManager->clear();

您似乎已经清除了所有未使用的对象和变量,您也可以尝试在php

中调用手册gc_collect_cycle
gc_collect_cycles();

如果您使用Symfony命令执行导入,请确保使用--no-debug flag

启动它

尽管没有达到完整的内存中立性,但在我的项目中与导入命令的工作正常,但其余的泄漏可以忽略不计。也许这在您的情况下可能会有所帮助。

我永远不会在冲洗后坚持50个实体。尝试将$ i降低到50或更少。也许有帮助。

相关内容

  • 没有找到相关文章

最新更新