Проблема с ограничением памяти в php

#php #memory #64-bit #limit

#php #память #64-разрядный #ограничение

Вопрос:

у меня проблема с памятью в php. Я установил ограничение в php.ini на 512 M

вывод /var/log/apache2/error.log является:

Неустранимая ошибка PHP: разрешенный объем памяти в 536870912 байт исчерпан (пытался выделить 71 байт) в /var/www/phpgraphlib.php в строке 578,

интересный фрагмент кода:

  foreach ($saved_test_figurestoprint as $figuretoprint){
        if (strpos($obj[$figuretoprint],",") >0 ){
  $graphfilename= "graphfile".remove_invalid_chars_for_file($obj["_id"])."_".remove_invalid_chars_for_file($figuretoprint).".png" ;        
        $graph = new PHPGraphLib(1000,200,$graphfilename);
        $data = explode(',', $obj[$figuretoprint]); 
$graph->addData($data);
$graph->setTitle($figuretoprint);
$graph->setBars(false);
$graph->setLine(true);
$graph->setDataPoints(true);
$graph->setDataPointColor('maroon');
$graph->createGraph();
?> <td> <?  echo $figuretoprint ; ?></td> <td> <? 
echo <<<END
<imag src=$graphfilename>
END

?> </td></tr><tr><?
echo "</br></br>";
echo "used memory is ".memory_get_usage(true) . "n";   
  

последний вывод:
используемая память равна 30408704

я использую 64-разрядную Ubuntu и php 5.3. Linux mongo-db-server 2.6.35-28-generic # 49-Ubuntu SMP Вт 1 марта 14:39:03 UTC 2011 x86_64 PHP версии 5.3.3-1ubuntu9.3 проблема возникает, если требуется нарисовать > 40 изображений.

я думаю, что новое ограничение памяти не было применено к серверу, я обнаружил эту ошибкуhttp://bugs.php.net/52061 но только для ограничений памяти > 2 ГБ

можете ли вы мне помочь?

Комментарии:

1. Мне было бы интересно получить выходные данные вашей последней строки (используемая память равна …).

2. Также взгляните на memory_get_peak_usage

3. уничтожьте / отмените настройку вашего класса PHPGraphLib…

4. я добавил unset ($ graph); echo «используемая память равна «.memory_get_usage (true) . » n»; echo «пик памяти равен «.memory_get_peak_usage(true) . » n»; и выходные данные остаются на тех же уровнях, используемая память равна 30670848, пик памяти равен 34340864. Это слишком мало по сравнению с моим лимитом в 512 МБ

5. еще раз здравствуйте. я решил проблему. похоже, что в базе данных mongo была определенная запись, которая была причиной этого. по какой-то причине это сохраняло огромные объемы памяти. возможно, он поврежден. я удалил ее, и теперь все работает гладко.

Ответ №1:

Первое, что я бы сделал, это убедиться, что вы полностью перезапускаете свой веб-сервер после внесения изменений в php.ini.

Если это не сработает, попробуйте это:

  1. Убедитесь, что вы записываете в правильный файл php.ini. Создайте info.php файл и убедитесь, что вы записываете в правильный.

  2. В нижней части вашего цикла for выполните:

сбросить значение ($graph); сбросить значение ($data);

Похоже, что это самые большие переменные, которые явно накапливают данные и не обрабатываются сборщиком мусора.

Комментарии:

1. Я не думаю, что отмена установки переменных поможет, переназначение переменных в верхней части цикла дает сборщику мусора понять, что старую память можно освободить.

2. Я видел сценарии, в которых сборщик мусора просто недостаточно быстр. Это может быть одной из них. Отмена установки переменных не повредит.

Ответ №2:

PHP unset просто удаляет ссылку на объект, и это не очищает выделение памяти внутреннего объекта, поэтому в итерационном процессе, когда вы каждый раз создаете большие объекты, затем выполняйте функцию уничтожения вашего объекта и в этой функции отключайте все используемые переменные класса, тогда только отключение основного объекта освободит всю память, которую он занимает.. надеюсь, этот факт кому-нибудь поможет

Комментарии:

1. unset($variableReferringToA) уменьшает счетчик ссылок объекта A , а также счетчики ссылок всех объектов B , C , D , … на которые A ссылается единица. Когда счетчик для объекта достигает 0, объект может / будет удален из памяти. Таким образом, вы могли бы сказать, что это unset работает рекурсивно. Нет необходимости писать деструктор класса для unset всех переменных экземпляра.