3

問題:

以下の Factory クラスから Doctrine を使用する Daemon サービスを実行しているときに、メモリの問題が発生します。Daemon Service が開始されると、約 175MB が実行されます。1 日後には約 250MB になり、さらに 1 日後には 400MB になります。何がメモリの増加を引き起こしているのか、どうすればそれを下げることができるのかを調べています。

私が試したこと:

  • $em->clear(); // これはちょっと役に立ちます
  • $em->close(); // これにより問題が発生します
  • $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
        }
    }
}

===================== END EMファクトリー =====================

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);

===================== END 作業例 #1 =====================

EM の使用方法の別の例を次に示します。クラスは上記の抽象クラスを拡張します。

===================== START 作業例 #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 の使用方法の別の例を次に示します。クラスは上記の抽象クラスを拡張します。

===================== START 作業例 #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 =====================

これらは基本的な例にすぎませんが、より複雑になるのはクエリだけです。

「私を最適化してください」と何か目立つものはありますか?

4

2 に答える 2