2015-03-23 2 views
3
dump("Before Memory: " . LogUtility::getMemoryUsage()); 
    $this->_em->getConnection()->getConfiguration()->setSQLLogger(null); 
    $start = $i*self::COUNT; 
    $entityName = $this->getEntityName(); 

    $query = $this->_em->createQueryBuilder()->select("c")->from($entityName, "c"); 
    $query->setFirstResult($start); 
    $query->setMaxResults(self::COUNT); 
    $query = $query->getQuery(); 
    $query->useQueryCache(false); 
    $query->useResultCache(false); 


    $result = $query->getResult(Query::HYDRATE_OBJECT); 
    //$query->expireQueryCache(true); 
    //unset($result); 

    for($i=0;$i<count($result);$i++): 
     $this->_em->detach($result[$i]); 
    endfor; 
    $this->_em->clear(); 
    @$query = null; 
    @$result = null; 
    unset($query,$result); 

    dump("After Memory: " . LogUtility::getMemoryUsage()); 

Эй, я с ума сошел с этим кодом. Я пытаюсь освободить память после этого призыва доктрины около 5000 сущностей, но он не освободит память, и я действительно не понимаю, почему.Доктрина и память

"Before Memory: 19.5 mb" 
"After Memory: 80 mb" 

Я попытался отсоединение, клиринга, незаходимая, функции самоуничтожения, свободная функция, используя sqllogger, кэш, Im становится совершенно безумен прямо сейчас!
Плюс Если я использую HYDRATE_ARRAY, я могу легко отключить переменную var и свободную память, но когда ее объект станет проблемой, это станет проблемой. Мои связанные с ними предприятия все имеют работу открепление каскадный и Yea В случае, если вы спрашиваете меня, если способ сообщить память хорошая Heres функция

static public function getMemoryUsage() { 
     $size = memory_get_usage(true); 
     $unit=array('b','kb','mb','gb','tb','pb'); 
     $size = @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i]; 
    return $size; 
} 

Спасибо за вашу помощь это сводит меня с ума !! Оу, а также, это запускается из командной строки вызова контроллера, который извлекает хранилище, контроллер так просто

__construct(EntityManager $em, Logger $logger); 

public function executeAction(){ 
    $this->repo->updateData(0); 
} 

EDIT: Также пробовал не используя gc_collect_cycles(), никакой разницы

edit2 : Мне нужен объект, потому что я собираюсь его обновить. В противном случае потребовался бы массив, и проблема была бы решена.

EDIT3: Также очищена папка журнала, у меня заканчиваются опции, и я не могу позволить освободить память, потому что скрипт обновит объекты 50k.

========================== SOLUTION ================================== 

$iterableResult= $query->iterate(); 
    foreach ($iterableResult as $row) { 
     $this->_em->detach($row[0]); 
    } 

"Memory: 19.5 mb" 
"Memory: 34.5 mb" 

Решение в функции итерации, которая должна иметь какой-то механизм, который заставляет его работать! Так что в принципе, не думайте, что это только отрыв, вы ДОЛЖНЫ использовать класс доктрины итерации для этой обработки bash! Теперь theres 10Mb над головой, но Im не собираюсь вытащить мои волосы, чтобы понять, куда он пошел. В любом случае, вы идете, ребята! Когда доктрина дает вам способ сделать это, КОПИРУЙТЕ это! Во всяком случае, если кто-то может объяснить нам, почему функция итерации имеет эту специальную магию, было бы здорово, если бы другие люди прошли ту же самую борьбу.

http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html

+0

У меня была проблема с переполнением памяти с догмой doctrine и очень большим набором данных, потребовалось ~ 4 ГБ памяти, а мой скрипт спустился. Я застрял в этом несколько дней и почти сошел с ума, поэтому, в конце концов, я переписал с помощью собственных драйверов, у меня было минимальное использование памяти, и он плавно очищал память. – Dmytro

+0

Это поудобно пошло на круговые ссылки и частично, так как работает GC в PHP. –

ответ

0

Doctrine2 известно, есть некоторые утечки памяти во время длительных операций. См. this blogpost, например

В моем случае отключение регистратора спасло мне некоторую память, но не все.

$this->em->getConnection()->getConfiguration()->setSQLLogger(null); 
Смежные вопросы