0

How to force clean memory on PHP? Version PHP: 5.5

My symfony2 command:

namespace NNNN\NNNN\Command;

use NNNN\NNNN\Model\Newsletter;
use NNNN\NNNN\Model\NewsletterQuery;
use NNNN\NNNN\Model\UsersNewslettersQuery;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;


class UsersNewslettersFixCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('users:newsletters:fix')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $counter = 0;
        $users = UsersNewslettersQuery::create()
            ->setFormatter(\ModelCriteria::FORMAT_ON_DEMAND)
            ->find();

        foreach ($users as $user) {
            if ($city = $user->getCity()) {
                $countryId = $city->getCountryId();
            } elseif ($location = $user->getLocation()) {
                $countryId = $location->getCountryId();
            } elseif ($region = $user->getRegion()) {
                $countryId = $region->getCountryId();
            }
            if (isset($countryId)) {
                $user->setCountryId($countryId);
                $user->save();
            }
            ++$counter;
        }

        $output->writeln('Handled '.count($counter).' users');
    }
}

How to force clean memory after some iterattion? gc_collect_cycles after ++$counter does not effect on memory using.

get_memory_usage output: enter image description here

NikiC
  • 100,734
  • 37
  • 191
  • 225
korvinko
  • 700
  • 3
  • 10
  • 23

1 Answers1

0

This is a general problem with most ORMs. They tend to use additional memory in order to improve performance. Unfortunately, you will occasionally find a time when they use too much memory.

The solution is just don't use an ORM when you run into these situations. Switch to something lower level like PDO instead when you need to process a huge amount of data.

$dbh = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);

$statement = $dbh->prepare("
  select * from users
  where !countryId
");
$statement->execute();

$updateStatement = $dbh->prepare("
  update user set countryId = :countryId
");
while ($user = $statement->fetchObject()) {
  // find countryId

  $updateStatement->execute(array(
    'countryId' => $countryId
  ));
}

That will only use a few KB of memory and execute extremely fast (as long as you have appropriate indexes in the database).

Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110