23 de março de 2011

Verificar memória ocupada numa task symfony

Quem usa objectos em PHP já se deve ter deparado com esta frase:

As of version 5.2.5, PHP is not able to garbage collect object graphs that have circular references, e.g. Parent has a reference to Child which has a reference to Parent. Since many doctrine model objects have such relations, PHP will not free their memory even when the objects go out of scope.

Ou seja, para objectos mais "complexos" nem o unset() resulta pois o PHP não consegue libertar os objectos ligados, que é o caso dos objectos model.
Nesse caso o symfony tenta dar uma ajuda com o método $meu_objecto->free().
Ou seja, para limpar:
$meu_objecto->free();
unset($meu_objecto);

Mesmo assim já tive casos em que isso não resolveu completamente e a solução foi não usar o Doctrine, outras vezes executar o ciclo um número limitado de vezes dentro do mesmo processo (task).
Para calcular o número de ciclos que o processo aguenta antes de recebntar com a memória usei este pedaço de código dentro do ciclo (de uma task) para ir vendo como evolui o consumo de memória.

//memory check
$memOld = $memNow;
$memNow = memory_get_usage();
$this->log('Memory usage: ' . $memNow . ' (diff=' . ($memNow - $memOld) . ')';

7 de março de 2011