我尝试将一些文档从 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 的内存耗尽错误?