Создание 100 — 200 тыс. PDF-файлов через Magento / Zend_Pdf приводит к утечке памяти

Просьба к сведению

Я знаю, что было бы проще использовать другую библиотеку PHP Pdf, но сейчас PDF-файлы представляют собой модифицированные счета-фактуры из Magento — и мне нужны полные объекты заказа / счета, поэтому, пожалуйста, имейте в виду, что в настоящее время нет другого выбора, кроме как использовать Zend_Pdf


Я пытался в течение трех долгих дней, но кажется, что Zend_Pdf через Zend_Pdf_ElementFactory утечки памяти.

Каждый раз, когда я запускаю этот код (работает в цикле foreach):

protected function _createInvoices($from, $to)
{
$invoiceCollection = Mage::getModel('sales/order_invoice')->getCollection()
->addFieldToFilter('created_at', array('from' => $from, 'to' => $to));

$invoiceCollection->setPageSize(self::PAGE_SIZE);
$lastPage = $invoiceCollection->getLastPageNumber();
$currentPage = 1;

// counting created invoices
$id = 1;

$path = $this->_getPath();

...

do {
$invoiceCollection->setCurPage($currentPage);
$invoiceCollection->load();

...

foreach($invoiceCollection as $invoice) {
// this is a custom class that extends Mage_Sales_Model_Order_Pdf_Invoice
$pdfModel = Mage::getModel('foo_bar/magic');

$pdf = $pdfModel->getPdf(array($invoice));

$pdf->save($pathName . '.pdf');

$id++;
}
...

$currentPage++;
$invoiceCollection->clear();
} while ($currentPage <= $lastPage);
}

С помощью memory_get_usage() непосредственно перед и после вышеприведенного кода использование увеличивается примерно на 20 кбайт для 500 или около того элементов, но это никоим образом не является линейным:

25250040 before getPdf
25431976 after and save getPdf
25433736 before getPdf
25564104 after and save getPdf
25565864 before getPdf
26625368 after and save getPdf
26627128 before getPdf
26748576 after and save getPdf
26750344 before getPdf
26929712 after and save getPdf
26931472 before getPdf
27045440 after and save getPdf
27047200 before getPdf
27273648 after and save getPdf
27275440 before getPdf
27410240 after and save getPdf

Теперь я попробовал использовать unset($pdf),

Я также вошел в класс Zend_Pdf и создал метод __destruct, чтобы установить все защищенные переменные на ноль, а также сброс их.

После большой отладки и использования XGui, чтобы увидеть использование памяти:

Обратите внимание на Zend_Pdf_ElementFactory (_Proxy) :: listModifiedObjects

Есть метод в Zend_Pdf_ElementFactory какая цель как указано:

* PDF element factory.
* Responsibility is to log PDF changes

и в очереди 365 общественная функция listModifiedObjects является:

/**
* Enumerate modified objects.
* Returns array of Zend_Pdf_UpdateInfoContainer
*
* @param Zend_Pdf_ElementFactory_Interface $rootFactory
* @return array
*/
public function listModifiedObjects($rootFactory = null)
{
...

foreach ($this->_attachedFactories as $factory) {
$result += $factory->listModifiedObjects($rootFactory);
}

return $result;
}

это foreach рекурсивно называет себя для всех присоединенных фабрик … я предполагаю, что именно здесь моя память теряется …

Пожалуйста, если у вас есть какие-нибудь подсказки или указания, чтобы указать мне, как работает Zend_Pdf_ElementFactory или как я мог его очистить (есть метод close, но, насколько я вижу, он нигде не вызывается), я был бы очень признателен!

Большое спасибо за помощь 🙂

PS: если что-то неясно, я рад предоставить более подробную информацию / информацию

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]