问题:
在运行使用下面工厂类中的 Doctrine 的守护进程服务时,存在内存问题。当守护进程服务启动时,它运行大约 175MB。一天后它大约是 250MB,再过一天它就变成了 400MB。我正在寻找导致内存增加的原因以及如何降低内存。
我尝试过的事情:
- $em->clear();//这有点帮助
- $em->关闭();//这会导致问题
$em->getConnection()->getConfiguration()->setSQLLogger(null);
--env=prod 应该处理 setSQLLogger(null),对吗?
我应该做些什么来帮助解决使用 Doctrine 2.x 和 Symfony 2.1.x 的内存问题?
创建了一个工厂来处理连接
===================== 启动 EMFactory =====================
<?php
namespace NS\Bundle\EMBundle;
use Doctrine\ORM\EntityManager;
class EMFactory
{
/**
* @var
*/
private $container;
/**
* @param $container
*/
public function __construct($container)
{
$this->container = $container;
}
/**
* @return EntityManager
*/
public function getBlahEntityManager()
{
return $this->getContainer()->get('doctrine.orm.blah_manager_entity_manager');
}
/**
* @return EntityManager
*/
public function getFooEntityManager()
{
return $this->getContainer()->get('doctrine.orm.foo_manager_entity_manager');
}
/**
* @return EntityManager
*/
public function getBarEntityManager()
{
return $this->getContainer()->get('doctrine.orm.bar_manager_entity_manager');
}
/**
* @return mixed
*/
public function getContainer()
{
return $this->container;
}
/**
* @param $container
* @return $this
*/
public function setContainer($container)
{
$this->container = $container;
return $this;
}
public function closeEntityManager(EntityManager $em)
{
try {
$em->clear(); // This kinda helps
//$em->close(); // this causes issues
//$em->getConnection()->getConfiguration()->setSQLLogger(null); // --env=prod should take care of this
} catch (\Exception $e) {
// exception here
}
}
}
===================== 结束 EMFactory =====================
我使用构造 EMFactory 的抽象类
=====================启动抽象类=====================
/**
* @param \Symfony\Component\DependencyInjection\Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
$this->entityManagerFactory = new EMFactory($container);
}
=====================结束抽象类=====================
这是我如何使用 EM 的示例,该类扩展了上面的抽象类
===================== 开始工作示例 #1 =====================
// calling like this looks to be working as expected
$fooEM = $this->getEntityManagerFactory()->getFooEntityManager();
$barResults = $fooEM->getRepository('NS\Bundle\EMBundle\Entity\Bar')->findOneBy(array('id' => 1));
if (!is_object($barResults)) {
throw new \Exception("Bar is a non object.");
}
// some logic here ...
$this->getEntityManagerFactory()->closeEntityManager($fooEM);
===================== 结束工作示例 #1 =====================
这是我如何使用 EM 的另一个示例,该类扩展了上面的抽象类
===================== 开始工作示例 #2 =====================
// calling from functions like this
$fooEM = $this->getEntityManagerFactory()->getFooEntityManager();
$dql = 'SELECT b.*
FROM NS\Bundle\EMBundle\Entity\Bar b
WHERE b.id = :id';
$query = $fooEM->createQuery($dql);
$query->setParameter('id', 1);
$barResults = $query->getResult();
$this->getEntityManagerFactory()->closeEntityManager($fooEM);
return $barResults;
===================== 结束工作示例 #2 =====================
这是我如何使用 EM 的另一个示例,该类扩展了上面的抽象类
===================== 开始工作示例 #3 =====================
// calling from functions like this
$fooEM = $this->getEntityManagerFactory()->getFooEntityManager();
$barEntity = new Bar();
$barEntity->setId(1);
$barEntity->setComment('this is foo-ie');
$fooEM->persist($barEntity);
$fooEM->flush();
$this->getEntityManagerFactory()->closeEntityManager($fooEM);
unset($barEntity);
===================== 结束工作示例 #3 =====================
这些只是一些基本示例,但只是查询变得更加复杂。
有什么突出的说,优化我吗?
最佳答案
您的问题可能来自实体管理器的实例化。如果你有一组特定的它们,你可能宁愿使用 Symfony2 依赖注入(inject)而不是调用容器。
每次使用访问器时,您都会实例化一个新的实体管理器,因此会消耗更多内存(并且由于它是守护进程,您永远不会真正释放它)。通过使用 DI,您将始终拥有相同的实例。
您的 EMFFactory 应该如下所示:
<?php
namespace NS\Bundle\EMBundle;
use Doctrine\ORM\EntityManager;
class EMFactory
{
/**
* @var
*/
private $fooEm;
/**
* @var
*/
private $barEm;
/**
* @var
*/
private $blahEm;
/**
* @param $fooEm
* @param $barEm
* @param $blahEm
*/
public function __construct($fooEm, $barEm, $blahEm)
{
$this->fooEm = $fooEm;
$this->barEm = $barEm;
$this->blahEm = $blahEm;
}
/**
* @return EntityManager
*/
public function getBlahEntityManager()
{
return $this->blahEm;
}
/**
* @return EntityManager
*/
public function getFooEntityManager()
{
return $this->fooEm;
}
/**
* @return EntityManager
*/
public function getBarEntityManager()
{
return $this->barEm;
}
/**
* @return mixed
*/
public function getContainer()
{
return $this->container;
}
/**
* @param $container
* @return $this
*/
public function setContainer($container)
{
$this->container = $container;
return $this;
}
public function closeEntityManager(EntityManager $em)
{
try {
$em->clear(); // This kinda helps
//$em->close(); // this causes issues
//$em->getConnection()->getConfiguration()->setSQLLogger(null); // --env=prod should take care of this
} catch (\Exception $e) {
// exception here
}
}
}
然后,调整您的服务定义以将各种 EM 提供给您的配置,并将您的 EMFactory 定义为服务。
关于php - Doctrine ORM 内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15572384/