Проблема:
При запуске службы Daemon, которая использует Doctrine из нижеприведенных классов Factory, возникает проблема с памятью. Когда служба Daemon запускается, она запускается около 175 МБ. Через день это около 250 МБ, еще один день, и он составляет 400 МБ. Я смотрю, что вызывает увеличение памяти и как я могу ее сбить.
Вещи, которые я пробовал:
$ 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 } } }
===================== КОНЕЦ EMFactory ================================================================
Я использую абстрактный класс, который создает EMFactory
===================================================================== ===
/** * @param \Symfony\Component\DependencyInjection\Container $container */ public function __construct(Container $container) { $this->container = $container; $this->entityManagerFactory = new EMFactory($container); }
===================== END Аннотация Класс ======================
Вот пример того, как я использую EM, класс расширяет класс Abstract выше
===================== Рабочий рабочий пример # 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);
===================== END Рабочий пример # 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 =====================
Это всего лишь некоторые базовые примеры, но это просто вопросы, которые становятся более сложными.
Есть ли что-то отличное, что говорят: «Оптимизируйте меня?
Ваша проблема может возникнуть из-за ваших указаний руководителей ваших организаций. Если у вас есть определенный набор из них, вы можете скорее использовать инъекцию зависимостей Symfony2 вместо вызова контейнера.
Каждый раз, когда вы используете своих аксессуаров, вы создаете новый Entity Manager, следовательно, потребляете больше памяти (и, поскольку это демон, вы никогда его не выпускаете). Используя 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 как услугу.
Это решило проблему связи, с которой мы столкнулись.
Необходимо закрыть только соединение
public function closeEntityManager(EntityManager $em) { try { $em->clear(); // This kinda helps $em->getConnection()->close(); // this seems to work } catch (\Exception $e) { // exception here } }