每次循环后内存使用量增加
Memory usage increasing after every loop
我有一个 foreach 循环,读取一个包含大约 200000 行的文件,这是我的 PHP :
foreach ($this->file as $row)
{
if ($this->file->valid())
{
//init client array
$this->initInvoicesArray($row);
$this->prepareInvoice();
$row = null;
$this->key = $this->file->key();
//add msisdn to msisdn array, and client to clients array
self::$MsisdnArray[] = $this->msisdn;
self::$InvoicesArray[$this->msisdn] = $this->client;
if ($i % 3000 == 0)
{
//get valid users from table
$this->prepareAndSaveValidClients();
}
$i++;
}
}
这是 prepareAndSaveValidClients() 函数:
public function prepareAndSaveValidClients(){
$query = Doctrine_Query::create()
->select('p.gender, p.email2, u.username, u.first_name, u.last_name, u.email_address, u.is_active, p.msisdn, p.user_id, p.city_id, p.street, p.zipcode, p.msisdn_status')
->from('sfGuardUser u')
->innerJoin('u.Profile as p ON u.id = p.user_id')
->whereIn('p.msisdn', self::$MsisdnArray)
->whereIn('p.status', self::$AllowedStatus);
$results = $query->fetchArray();
//instanciat an object collection for payment_notifications
$collection = new Doctrine_Collection("payment_notifications");
if (!empty($results))
{
foreach ($results as $key => $client)
{
$invoice = self::$InvoicesArray[$client['Profile']['msisdn']];
$this->initInvoicesArray($invoice);
$this->prepareInvoice();
$this->prepareUserProfile($client);
$this->prepareClient();
$paymentNotifications = new paymentNotifications();
$paymentNotifications->fromArray($this->client);
$collection->add($paymentNotifications);
$tel = $client['Profile']['msisdn'];
$client = null;
}
$collection->save();
//clear memory
$results = null;
$collection = null;
self::$MsisdnArray = null;
self::$InvoicesArray = null;
$this->logSection('tel num', 'added :' . $tel . ' Memory usage : ' . memory_get_usage());
$duration = microtime(true) - $this->startTime;
$this->logSection('payment : ', sprintf('added in %s', $duration));
}
}
至于功能:
$this->initInvoicesArray($invoice);
$this->prepareInvoice();
$this->prepareUserProfile($client);
$this->prepareClient();
他们只是为了准备$this->client
这是为每个循环显示的内存使用情况:
>> tel num added :0699946185 Memory usage : 89287596
>> payment : added in 8.6373870372772
>> tel num added :0699983919 Memory usage : 165854544
>> payment : added in 18.373502969742
>> tel num added :0699949623 Memory usage : 241338788
>> payment : added in 29.336947917938
>> tel num added :0699854750 Memory usage : 319173092
>> payment : added in 40.880628824234
如您所见,我试图释放这些变量的内存:
$results = null;
$collection = null;
self::$MsisdnArray = null;
self::$InvoicesArray = null;
但徒劳无功,每次循环后内存使用量都在增加,这导致了一个 Allowed Memory size exausted
致命错误。我该如何优化它?
谢谢。
Doctrine 对象具有 php 难以释放的循环引用。为了解决这个问题,doctrine 提供了 free()
方法,在设置为 null 之前在集合上调用它:
$collection->free(true);
$collection = null;
调用 $this->prepareAndSaveValidClients();
后,您还可以使用 gc_collect_cycles()
函数。它将有助于解决可能的内存泄漏问题。
我2个月前解决了这个问题,Memory_usage变得稳定了,但是我忘了post这里的解决方案
我做的是I removed Doctrine, and I used mere PDO and Sql for the select query
.
我有一个 foreach 循环,读取一个包含大约 200000 行的文件,这是我的 PHP :
foreach ($this->file as $row)
{
if ($this->file->valid())
{
//init client array
$this->initInvoicesArray($row);
$this->prepareInvoice();
$row = null;
$this->key = $this->file->key();
//add msisdn to msisdn array, and client to clients array
self::$MsisdnArray[] = $this->msisdn;
self::$InvoicesArray[$this->msisdn] = $this->client;
if ($i % 3000 == 0)
{
//get valid users from table
$this->prepareAndSaveValidClients();
}
$i++;
}
}
这是 prepareAndSaveValidClients() 函数:
public function prepareAndSaveValidClients(){
$query = Doctrine_Query::create()
->select('p.gender, p.email2, u.username, u.first_name, u.last_name, u.email_address, u.is_active, p.msisdn, p.user_id, p.city_id, p.street, p.zipcode, p.msisdn_status')
->from('sfGuardUser u')
->innerJoin('u.Profile as p ON u.id = p.user_id')
->whereIn('p.msisdn', self::$MsisdnArray)
->whereIn('p.status', self::$AllowedStatus);
$results = $query->fetchArray();
//instanciat an object collection for payment_notifications
$collection = new Doctrine_Collection("payment_notifications");
if (!empty($results))
{
foreach ($results as $key => $client)
{
$invoice = self::$InvoicesArray[$client['Profile']['msisdn']];
$this->initInvoicesArray($invoice);
$this->prepareInvoice();
$this->prepareUserProfile($client);
$this->prepareClient();
$paymentNotifications = new paymentNotifications();
$paymentNotifications->fromArray($this->client);
$collection->add($paymentNotifications);
$tel = $client['Profile']['msisdn'];
$client = null;
}
$collection->save();
//clear memory
$results = null;
$collection = null;
self::$MsisdnArray = null;
self::$InvoicesArray = null;
$this->logSection('tel num', 'added :' . $tel . ' Memory usage : ' . memory_get_usage());
$duration = microtime(true) - $this->startTime;
$this->logSection('payment : ', sprintf('added in %s', $duration));
}
}
至于功能:
$this->initInvoicesArray($invoice);
$this->prepareInvoice();
$this->prepareUserProfile($client);
$this->prepareClient();
他们只是为了准备$this->client
这是为每个循环显示的内存使用情况:
>> tel num added :0699946185 Memory usage : 89287596
>> payment : added in 8.6373870372772
>> tel num added :0699983919 Memory usage : 165854544
>> payment : added in 18.373502969742
>> tel num added :0699949623 Memory usage : 241338788
>> payment : added in 29.336947917938
>> tel num added :0699854750 Memory usage : 319173092
>> payment : added in 40.880628824234
如您所见,我试图释放这些变量的内存:
$results = null;
$collection = null;
self::$MsisdnArray = null;
self::$InvoicesArray = null;
但徒劳无功,每次循环后内存使用量都在增加,这导致了一个 Allowed Memory size exausted
致命错误。我该如何优化它?
谢谢。
Doctrine 对象具有 php 难以释放的循环引用。为了解决这个问题,doctrine 提供了 free()
方法,在设置为 null 之前在集合上调用它:
$collection->free(true);
$collection = null;
调用 $this->prepareAndSaveValidClients();
后,您还可以使用 gc_collect_cycles()
函数。它将有助于解决可能的内存泄漏问题。
我2个月前解决了这个问题,Memory_usage变得稳定了,但是我忘了post这里的解决方案
我做的是I removed Doctrine, and I used mere PDO and Sql for the select query
.