いくつかのドキュメントを mongodb から .csv にエクスポートしようとしています。一部の大きなリストの場合、ファイルは 40M 程度になり、メモリ制限に関するエラーが発生します。
Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 44992513 bytes) in
/usr/share/php/Zend/Controller/Response/Abstract.php on line 586
なぜこのエラーが発生するのだろうか。そのような量のメモリを消費するのは何ですか? memory_limit
現在設定されているものを変更せずに、このようなエラーを回避するにはどうすればよいですか128M
。
私は次のようなものを使用します:
public static function exportList($listId, $state = self::SUBSCRIBED)
{
$list = new Model_List();
$fieldsInfo = $list->getDescriptionsOfFields($listId);
$headers = array();
$params['list_id'] = $listId;
$mongodbCursor = self::getCursor($params, $fieldsInfo, $headers);
$mongodbCursor->timeout(0);
$fp = fopen('php://output', 'w');
foreach ($mongodbCursor as $subscriber) {
foreach ($fieldsInfo as $fieldInfo) {
$field = ($fieldInfo['constant']) ? $fieldInfo['field_tag'] : $fieldInfo['field_id'];
if (!isset($subscriber->$field)) {
$row[$field] = '';
} elseif (Model_CustomField::isMultivaluedType($fieldInfo['type'])) {
$row[$field] = array();
foreach ($subscriber->$field as $value) {
$row[$field][] = $value;
}
$row[$field] = implode(self::MULTIVALUED_DELEMITOR, $row[$field]);
} else {
$row[$field] = $subscriber->$field;
}
}
fputcsv($fp, $row);
}
}
次に、コントローラーで次のように呼び出します。
public function exportAction()
{
set_time_limit(300);
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$fileName = $list->list_name . '.csv';
$this->getResponse()->setHeader('Content-Type', 'text/csv; charset=utf-8')
->setHeader('Content-Disposition', 'attachment; filename="'. $fileName . '"');
Model_Subscriber1::exportList($listId);
echo 'Peak memory usage: ', memory_get_peak_usage()/1024, ' Memory usage: ', memory_get_usage()/1024;
}
したがって、データをエクスポートするファイルの最後にいます。1M ドキュメントのようなものでエクスポートしたリストが正常にエクスポートされ、次のように表示されるのはかなり奇妙です。
> Peak memory usage: 50034.921875 Kb Memory usage: 45902.546875 Kb
しかし、1.3M のドキュメントをエクスポートしようとすると、数分後にエクスポート ファイルしか取得できません。
Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 44992513 bytes) in
/usr/share/php/Zend/Controller/Response/Abstract.php on line 586.
エクスポートするドキュメントのサイズはほぼ同じです。
memory_limit を 256M に増やし、1.3M のリストをエクスポートしようとしたところ、次のように表示されました。
ピーク メモリ使用量: 60330.4609375Kb メモリ使用量: 56894.421875 Kb。
私には非常に混乱しているようです。このデータはそれほど不正確ではありませんか? それ以外の場合、memory_limit を 128M に設定するとメモリ不足エラーが発生するのはなぜですか?