Пакетная обработка помогает!
Мне понадобилось много времени, чтобы понять, что помогает. У меня сложилось впечатление, что пока вы остаетесь в том же php-процессе, вы не можете освободить свою память. Так что это не помогло для меня:
- $ object-> бесплатно (правда)
- снят с охраной ($ объекта)
- sfConfig :: set ('sf_debug', false)
- gc_collect_cycles () / gc_enable ()
- Doctrine_Core :: HYDRATE_ON_DEMAND
- sfCommandApplicationTask :: runTask ()
- sfDoctrinePager
Что действительно помогло , так это подсказка от Rich Sage , который предложил порождать подпроцессы для выполнения частей работы. Предел и смещение для запроса задаются как параметры между процессами. Чтобы получить строку за строкой, установите $options['limit']
в 1, но 50 также должно быть хорошим значением:
daddyTask.class.php
[..]
$total = ItemTable::getInstance()->createQuery('i')->count();
for ($offset = 0; $offset < $total; $offset += $options['limit'] )
{
passthru(
sprintf('%s %s/symfony doTask --limit=%s --offset=%s', sfToolkit::getPhpCli(), sfConfig::get('sf_root_dir'), $options["limit"], $offset),
$returnVar
);
}
doTask.class.php
$items = ItemTable::getInstance()->createQuery('i')->limit($options['limit'])->offset($options['offset'])->execute();
foreach( $items as $item )
{
// ..do something with the item
$this->log( 'INFO: '.memory_get_peak_usage(true).' memory in use.' );
}
(я использую Doctrine 1.2 в платформе Symfony 1.4 на PHP 5.3.10)
Любые комментарии или критические замечания по этой теме очень ценятся, так как это трудно для меня!