В этом разделе описывается, как MATLAB ® распределяет память при работе с переменными. Эта информация, как и любая информация о том, как MATLAB обрабатывает данные внутри системы, может быть изменена в будущих версиях.
При назначении переменной числового или символьного массива MATLAB выделяет смежный блок памяти и сохраняет данные массива в этом блоке. MATLAB также хранит информацию о данных массива, таких как его класс и размеры, в небольшом отдельном блоке памяти, называемом заголовком. Для большинства массивов память, необходимая для хранения заголовка, незначительна. Однако может быть некоторое преимущество хранения больших наборов данных в небольшом количестве больших массивов в отличие от большого количества малых массивов. Это связано с тем, что меньшее количество массивов требует меньшего количества заголовков массива.
При добавлении новых элементов в существующий массив MATLAB расширяет массив в памяти таким образом, чтобы сохранить его непрерывность. Для этого обычно требуется найти новый блок памяти, достаточно большой для хранения расширенного массива. Затем MATLAB копирует содержимое массива из его исходного расположения в этот новый блок в памяти, добавляет новые элементы в массив в этом блоке и освобождает исходное расположение массива в памяти.
При удалении элементов из существующего массива MATLAB сохраняет память смежной, удаляя удаленные элементы, а затем сжимая ее в исходной папке памяти.
При назначении массива второй переменной (например, при выполнении B = A), MATLAB не выделяет новую память сразу. Вместо этого создается копия ссылки на массив. Пока вы не изменяете содержимое блока памяти, на который ссылается A и B, нет необходимости хранить более одной копии данных. Однако при изменении каких-либо элементов блока памяти A или BMATLAB выделяет новую память, копирует в нее данные, а затем изменяет созданную копию.
В системах с ОС Windows ® memory позволяет проверить подробные данные памяти. Чтобы увидеть, как копирование массивов влияет на использование памяти в системе Windows, создайте функцию memUsed в файле в текущей папке. Вызов функции memory для возврата объема памяти, используемого процессом MATLAB в мегабайтах.
function y = memUsed
usr = memory;
y = usr.MemUsedMATLAB/1e6;
Звонить memUsed для отображения текущего использования памяти.
format shortG
memUsedans =
3966.1
Создайте числовой массив 2000 на 2000 и наблюдайте за изменениями в использовании памяти. Массив использует около 32 МБ памяти.
A = magic(2000); memUsed
ans =
3998.1
Создать копию A в B. Поскольку нет необходимости иметь две копии данных массива, MATLAB создает только копию ссылки массива. Это не требует значительной дополнительной памяти.
B = A; memUsed
ans =
3998.1
Теперь изменить B путем удаления половины его рядов. Поскольку A и B больше не указывает на те же данные, MATLAB должен выделить отдельный блок памяти для B. В результате объем памяти, используемой процессом MATLAB, увеличивается на размер B, что составляет около 16 МБ (половина из 32 МБ, необходимых для A).
B(1001:2000,:) = []; memUsed
ans =
4014.1
MATLAB обрабатывает аргументы, передаваемые в вызовах функций, так же, как и копируемые массивы. При передаче переменной функции фактически передается ссылка на данные, которые представляет переменная. Пока данные не изменяются вызываемой функцией, переменная в вызывающей функции или сценарии и переменная в вызываемой функции указывают на одно и то же местоположение в памяти. Если вызываемая функция изменяет значение входных данных, то MATLAB создает копию исходной переменной в новом расположении в памяти, обновляет эту копию с измененным значением и указывает входной аргумент в вызываемой функции на это новое расположение.
Например, рассмотрим функцию myfun, который изменяет значение переданного ему массива. MATLAB делает копию A в новом расположении в памяти, задает переменную X в качестве ссылки на эту копию, а затем устанавливает одну строку X до нуля. Массив, на который ссылается A остается неизменным.
A = magic(5); myfun(A) function myfun(X) X(4,:) = 0; disp(X) end
Если вызывающей функции или сценарию требуется измененное значение массива, которому он передан myfun, необходимо вернуть обновленный массив как вывод вызываемой функции.
Требования к памяти различаются для типов данных MATLAB. Можно уменьшить объем памяти, используемой кодом, узнав, как MATLAB обрабатывает различные типы данных.
MATLAB выделяет 1, 2, 4 или 8 байт для 8-разрядных, 16-разрядных, 32-разрядных и 64-разрядных подписанных и неподписанных целых чисел соответственно. Он представляет числа с плавающей запятой с двойной точностью (double) или с одной точностью (single) формат. Поскольку MATLAB хранит номера типа single используя 4 байта, они требуют меньше памяти, чем числа типа double, которые используют 8 байт. Однако, поскольку они хранятся с меньшим количеством битов, количество типов single представлены с меньшей точностью, чем числа типа double. В MATLAB, double является числовым типом данных по умолчанию и обеспечивает достаточную точность для большинства вычислительных задач. Дополнительные сведения см. в разделе Номера с плавающей запятой.
В то время как числовые массивы должны храниться в непрерывном блоке памяти, структуры и массивы ячеек могут храниться в несмежных блоках. Для структур и массивов ячеек MATLAB создает заголовок не только для массива, но и для каждого поля структуры или каждой ячейки массива ячеек. Поэтому объем памяти, необходимый для хранения структуры или массива ячеек, зависит не только от того, сколько данных она хранит, но и от того, как она построена.
Например, рассмотрим скалярную структуру S1 с полями R, G, и B, где каждое поле содержит массив 100 на 50. S1 требуется один заголовок для описания общей структуры, один заголовок для каждого уникального имени поля и один заголовок для каждого поля. Это составляет в общей сложности семь заголовков для всей структуры.
S1.R = zeros(100,50); S1.G = zeros(100,50); S1.B = zeros(100,50);
С другой стороны, рассмотрим структурный массив 100 на 50 S2 в котором каждый элемент имеет скалярные поля R, G, и B. В этом случае S2 требуется один заголовок для описания общей структуры, один заголовок для каждого уникального имени поля и один заголовок для каждого поля из 5000 элементов, что составляет в общей сложности 15 004 заголовка массива для всего массива структуры.
for i = 1:100 for j=1:50 S2(i,j).R = 0; S2(i,j).G = 0; S2(i,j).B = 0; end end
Используйте whos функция для сравнения объема памяти, выделенной S1 и S2 в 64-разрядной системе. Несмотря на то, что S1 и S2 храните те же данные, S1 использует значительно меньше памяти.
whos S1 S2
Name Size Bytes Class Attributes S1 1x1 120504 struct S2 100x50 1680192 struct
MATLAB использует чередующееся представление памяти комплексных чисел, где действительная и мнимая части хранятся вместе в смежном блоке памяти. При создании копии сложного массива и последующем изменении только действительной или мнимой части массива MATLAB создает массив, содержащий как действительную, так и мнимую части. Дополнительные сведения о представлении комплексных чисел в памяти см. в разделе Поддержка MATLAB для перемежающегося комплексного API в функциях MEX.
Рекомендуется хранить матрицы с небольшим количеством ненулевых элементов, используя разреженное хранение. Когда полная матрица имеет небольшое количество ненулевых элементов, преобразование матрицы в разреженное хранилище обычно улучшает использование памяти и время выполнения кода. Полную матрицу можно преобразовать в разреженное хранилище с помощью sparse функция.
Например, пусть matrix A быть полной матрицей идентификаторов хранения данных 1000 на 1000. Создать B как разреженная копия A. В разреженном хранилище одни и те же данные используют значительно меньший объем памяти.
A = eye(1000); B = sparse(A); whos A B
Name Size Bytes Class Attributes A 1000x1000 8000000 double B 1000x1000 24008 double sparse
При работе с большими наборами данных многократное изменение размеров массивов может привести к исчерпанию памяти программы. При расширении массива за пределы доступной непрерывной памяти исходного местоположения MATLAB должен создать копию массива и переместить копию в блок памяти с достаточным объемом памяти. Во время этого процесса в памяти находятся две копии исходного массива. Это временно удваивает объем памяти, необходимый для массива, и увеличивает риск нехватки памяти. Можно увеличить использование памяти и время выполнения кода путем предварительного выделения максимального пространства, необходимого для массива. Дополнительные сведения см. в разделе Предварительное распределение.