Вот мой код, который создает массив 2d, заполненный нулями, размеры массива (795,6942):
function zeros($rowCount, $colCount){ $matrix = array(); for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ $matrix[] = array(); for($colIndx=0; $colIndx<$colCount; $colIndx++){ $matrix[$rowIndx][$colIndx]=0; } } return $matrix; } $matrix = zeros(795,6942);
И вот ошибка, которую я получаю:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes)
Есть идеи, как это решить?
В качестве быстрого вычисления вы пытаетесь создать массив, который содержит:
795*6942 = 5,518,890
целые числа.
Если мы считаем, что одно целое число хранится на 4 байта (то есть 32 бита, с использованием PHP это не меньше) , это означает:
5518890*4 = 22,075,560
байт.
ОК, быстрый расчет … результат « это должно быть ОК ».
Но дело не так просто, к несчастью 🙁
Я полагаю, это связано с тем, что данные хранятся в PHP с использованием внутренней структуры данных, которая намного сложнее, чем простое 32-битное целое число
Теперь, просто любопытно, давайте изменим вашу функцию, чтобы она выводила, сколько памяти используется в конце каждого из внешних for
-loop:
function zeros($rowCount, $colCount){ $matrix = array(); for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ $matrix[] = array(); for($colIndx=0; $colIndx<$colCount; $colIndx++){ $matrix[$rowIndx][$colIndx]=0; } var_dump(memory_get_usage()); } return $matrix; }
С этим я получаю такой вывод (PHP 5.3.2-dev в 64-битной системе, memory_limit
установлен в 128MB
– это уже много!) :
int 1631968 int 2641888 int 3651808 ... ... int 132924168 int 133934088 Fatal error: Allowed memory size of 134217728 bytes exhausted
Это означает, что каждая итерация внешнего for
-loop требует примерно 1,5 МБ памяти – и я получаю только 131 итерации до того, как у скрипта закончится память; и не 765, как вы хотели.
Учитывая, что вы установили свой memory_limit
в 128M
, вам придется установить его на что-то действительно намного выше – например,
128*(765/131) = 747 MB
Ну, даже с
ini_set('memory_limit', '750M');
его все еще недостаточно … с 800MB
, кажется, достаточно 😉
Но я определенно не рекомендую устанавливать memory_limit
на такое высокое значение!
(Если у вас 2 ГБ ОЗУ, ваш сервер не сможет обрабатывать более двух одновременных пользователей ^^ ;; я бы не стал проверять это, если бы на моем компьютере было 2 ГБ оперативной памяти, если честно)
Единственное решение, которое я вижу здесь, – это переосмыслить свой дизайн: нужно что-то еще сделать, чем использовать эту часть кода 🙂
(BTW: может быть, «передумать свой дизайн» означает использование другого языка PHP: PHP отлично подходит для разработки веб-сайтов, но не подходит для всех проблем)
Реализация PHP-массива по умолчанию очень интенсивно связана с памятью. Если вы просто храните целые числа (и их много), вы, вероятно, захотите посмотреть на SplFixedArray . Он использует регулярный непрерывный блок памяти для хранения данных, в отличие от традиционной хэш-структуры.
Вы должны попытаться увеличить объем памяти, доступной для PHP:
ini_set('memory_limit', '32M');
в вашем PHP-файле.