В этом разделе приведены сведения о том, как MATLAB ® выделяет память при работе с переменными. Эта информация, как и любая информация о том, как MATLAB обрабатывает данные внутренне, может быть изменена в будущих релизах.
Когда вы присваиваете переменной числовой или символьный массив, MATLAB выделяет непрерывный блок памяти и хранит данные массива в этом блоке. MATLAB также хранит информацию о данных массива, таких как его класс и размерности, в небольшом, отдельном блоке памяти, называемом заголовком. Для большинства массивов память, необходимая для хранения заголовка, незначительна. Однако может быть некоторое преимущество в хранении больших наборов данных в небольшом количестве больших массивов в отличие от большого количества небольших массивов. Это связано с тем, что меньшее количество массивов требует меньшего количества заголовков массивов.
Если вы добавляете новые элементы к существующему массиву, MATLAB расширяет массив в памяти таким образом, чтобы он оставался непрерывным. Обычно это требует нахождения нового блока памяти, достаточно большого для хранения расширенного массива. MATLAB затем копирует содержимое массива из его исходного местоположения в этот новый блок памяти, добавляет новые элементы в массив в этом блоке и освобождает исходное местоположение массива в памяти.
Если вы удаляете элементы из существующего массива, MATLAB сохраняет непрерывность памяти путем удаления удаленных элементов и последующего уплотнения его памяти в исходном месте памяти.
Когда вы присваиваете массив второй переменной (для образца, когда вы выполняете B = A
), MATLAB не выделяет новую память сразу. Вместо этого создается копия ссылки на массив. Пока вы не изменяете содержимое блока памяти, на который ссылаются A
и B
, нет необходимости хранить более одной копии данных. Однако, если вы изменяете какие-либо элементы блока памяти, используя A
или B
MATLAB выделяет новую память, копирует в нее данные, а затем изменяет созданную копию.
В системах Windows ® memory
функция позволяет вам проверить детали памяти. Чтобы увидеть, как копирование массивов влияет на использование памяти в вашей системе Windows, создайте функцию memUsed
в файле в текущей папке. Функция вызывает memory
чтобы вернуть объем памяти, используемый процессом MATLAB в мегабайтах.
function y = memUsed
usr = memory;
y = usr.MemUsedMATLAB/1e6;
Функции memUsed
чтобы отобразить текущее использование памяти.
format shortG
memUsed
ans = 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
функция.
Для примера пусть матрица 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 должен сделать копию массива и переместить копию в блок памяти с достаточным пространством. В течение этого процесса существует две копии исходного массива в памяти. Это временно удваивает объем памяти, необходимый для массива, и увеличивает риск нехватки памяти у вашей программы. Можно улучшить использование памяти и время выполнения кода, предварительно выделив максимальное пространство, необходимое для массива. Для получения дополнительной информации см. раздел Предварительное выделение.