Ошибка памяти PHP с большим массивом

Я пытаюсь создать 2D-массив в PHP размером 2000×2000 (4 миллиона записей). Кажется, мне здесь не хватает памяти, но способ появления ошибки сбивает меня с толку.

Когда я определяю массив и заполняю его изначально с помощью команды array_fill, и инициализирую каждую позицию в массиве (матрице) с 0, проблем не возникает.

Однако, если я попробую перебрать массив и заполнить каждую позицию 0, ему не хватит памяти.

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

Конечно, это просто упрощенная версия кода. В моем реальном приложении я буду использовать X & Y координирует поиск значения из другой таблицы, обрабатывает его, а затем сохраняет его в моей матрице. Это будут значения с плавающей запятой.

Может ли кто-нибудь помочь через этот свет, пожалуйста? Есть ли какой-то другой способ, которым я должен делать это?

Спасибо!

<?php

// Set error reporting.
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);

// Define Matrix dimensions.
define("MATRIX_WIDTH", 2000+1);
define("MATRIX_HEIGHT", 2000+1);// Setup array for matrix and initialize it.
$matrix = array_fill(0,MATRIX_HEIGHT,array_fill(0,MATRIX_WIDTH,0));

// Populate each matrix point with calculated value.
for($y_cood=0;$y_cood<MATRIX_HEIGHT;$y_cood++) {

// Debugging statement to see where the script stops running.
if( ($y_cood % 100) == 0 )  {print("Y=$y_cood<br>"); flush();}

for($x_cood=0;$x_cood<MATRIX_WIDTH;$x_cood++) {
$fill_value = 0;
$matrix[$y_cood][$x_cood]=$fill_value;
}
}

print("Matrix width: ".count($matrix)."<br>");
print("Matrix height: ".count($matrix[0])."<br>");

?>

5

Решение

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

И да и нет. Выделение памяти и выполнение программного кода — это два разных способа (обычно).
Память, выделенная для программы / процесса, обычно делится на две части — куча и стек. Когда вы «выделяете память» (в значении, которое вы использовали в своем вопросе), это происходит в куче. Когда вы выполняете программный код, также используется стек. Оба не разделены полностью, так как вы можете помещать и / или вставлять ссылки (указатели на кучу) в стек и / или из него.

Дело в том, что куча и стек разделяют часть памяти (выделенную этому процессу), и обычно одна увеличивается (заполняется) от старших адресов к младшим, а другая — от младших адресов к старшим, и так что у вас есть «плавающая» граница между ними. Как только обе части достигают этой «границы», вам «не хватает памяти».
введите описание изображения здесь

Итак, в вашем случае, когда вы создаете и заполняете свой массив (матрицу), вы используете память для 2001 x 2001 целых чисел. Если целое число требует 32 бита или 4 байта, то 2001 x 2001 x 4 байта = 4004001 x 4 байта = 16016004 байта ~ 16 МБ.
При выполнении кода стек заполняется (локальными) переменными — переменной условия цикла, счетчиком цикла и всеми другими переменными.
Вы также не должны забывать, что код PHP (библиотека) также должен быть загружен в память, поэтому в зависимости от значения, которое вы установили как memory_limit в вашей конфигурации вы можете быстро исчерпать память.

4

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

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

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