问题:
在运行使用以下Factory类中的Doctrine的守护进程服务时会出现内存问题。当守护进程服务启动时,它运行大约175MB。一天后它大约250MB,再多一天,它是400MB。我正在研究导致内存增加的原因以及如何将其降低。
我尝试过的事情:
$ EM->的getConnection() - > getConfiguration() - > setSQLLogger(空);
- env = prod应该处理setSQLLogger(null),对吗?
使用Doctrine 2.x和Symfony 2.1.x,我有什么办法可以帮助解决内存问题吗?
创建了一个处理连接的工厂
===================== START 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
}
}
}
===================== END EMFactory =====================
我使用构造EMFactory的抽象类
=====================开始抽象类=====================
/**
* @param \Symfony\Component\DependencyInjection\Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
$this->entityManagerFactory = new EMFactory($container);
}
===================== END抽象类=====================
以下是我如何使用EM的示例,该类扩展了上面的Abstract类
===================== START工作示例#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的另一个例子,该类扩展了上面的Abstract类
=====================开始工作示例#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;
===================== END工作示例#2 =====================
这是我如何使用EM的另一个例子,该类扩展了上面的Abstract类
=====================开始工作示例#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);
===================== END工作示例#3 =====================
这些只是一些基本的例子,但只是查询变得更复杂。
有什么突出的说法,优化我?
答案 0 :(得分:1)
您的问题可能来自您的实体经理的实例。如果你有一组特定的,你可能宁愿使用Symfony2依赖注入而不是调用容器。
每次使用访问器时,都会实例化一个新的实体管理器,因此消耗更多内存(因为它是一个守护进程,你永远不会真正释放它)。通过使用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定义为服务。
答案 1 :(得分:0)
这解决了我们遇到的连接问题。
需要关闭连接
public function closeEntityManager(EntityManager $em)
{
try {
$em->clear(); // This kinda helps
$em->getConnection()->close(); // this seems to work
} catch (\Exception $e) {
// exception here
}
}