Как MATLAB выделяет память

Выделение памяти для массивов

Эта тема предоставляет информацию о том, как MATLAB® выделяет память при работе с массивами и переменными. Цель состоит в том, чтобы помочь вам использовать память более эффективно когда написание кода. Наиболее часто, однако, вы не должны должны быть быть обеспокоены этими внутренними операциями, когда MATLAB обрабатывает хранение данных для вас автоматически.

Примечание

Любая информация о том, как программное обеспечение MATLAB обрабатывает данные внутренне, подвержена изменениям в будущих релизах.

Создание и изменение массивов

Когда вы присваиваете числовое или символьный массив к переменной, MATLAB выделяет непрерывный виртуальный блок памяти и хранит данные массива в том блоке. MATLAB также хранит информацию о данных массива, таких как его класс, и размерности, в отдельном, маленьком блоке памяти вызвали header.

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

Если вы удаляете элементы из существующего массива, MATLAB сохраняет устройство хранения данных памяти непрерывным путем удаления удаленных элементов, и затем уплотнения его устройства хранения данных в исходной ячейке памяти.

Работа с Большими наборами данных.  Если вы работаете с большими наборами данных, необходимо быть осторожными при увеличении размера массива, чтобы не получать ошибки, вызванные недостаточно памятью. Если вы расширяете массив вне доступной непрерывной памяти о его исходном местоположении, MATLAB должен сделать копию массива и установить эту копию на новое значение. Во время этой операции существует две копии исходного массива в памяти. Это временно удваивает объем памяти, требуемый для массива, и увеличивает риск вашей программы, исчерпывающей память во время выполнения. Лучше предварительно выделить достаточную память для самого большого потенциального размера массива в запуске. Смотрите Предварительное выделение.

Копирование массивов

Внутренне, несколько переменных могут указать на тот же блок данных, таким образом совместно использовав что значение массива. Когда вы копируете переменную в другую переменную (например, B = A), MATLAB делает копию ссылки на массив, но не сам массив. Пока вы не изменяете содержимое массива, нет никакой потребности сохранить больше чем одну копию его. Если вы действительно изменяете какие-либо элементы массива, MATLAB делает копию массива и затем изменяет ту копию.

Этот пример использует memory функция, чтобы продемонстрировать, как MATLAB обрабатывает копирование массивов. memory доступно только в системах Windows®.

Запустите путем создания простого скрипта memUsed.m отображаться, сколько памяти используется вашим процессом MATLAB. Поместите эти две строки кода в скрипт.

[usr, sys] = memory;
usr.MemUsedMATLAB

Получите начальное чтение того, сколько памяти используется вашим процессом MATLAB:

format short eng;
memUsed
ans =
   295.4977e+006

Создайте 2000 2000 числовой массив A. Это использует приблизительно 32 МБ памяти:

A = magic(2000);
memUsed
ans =
   327.6349e+006

Сделайте копию массива A в B. Как нет никакой потребности иметь две копии данных массива, MATLAB только делает копию ссылки на массив. Это не требует никакой значительной дополнительной памяти:

B = A;
memUsed
ans =
   327.6349e+006

Теперь измените B путем создания его одной половиной ее первоначального размера (то есть, устанавливает 1 000 строк пустеть). Это требует, чтобы MATLAB сделал копию, по крайней мере, первых 1 000 строк A массив и присвоение та копия к B:

B(1001:2000,:) = [];
format short;   size(B)
ans =
        1000        2000

Проверяйте память, используемую снова. Даже при том, что B значительно меньше, чем это было первоначально, объем памяти, используемый процессом MATLAB, увеличился приблизительно на 16 Мбайт (1/2 32 Мбайт, первоначально требуемых для A) потому что B больше не мог оставаться как только ссылка на A:

format short eng;   memUsed
ans =
   343.6421e+006

Заголовки массивов

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

Структура и Массивы ячеек.  Для структур и массивов ячеек, MATLAB создает заголовок не только для каждого массива, но также и для каждого поля структуры и для каждой ячейки массива ячеек. Из-за этого, объем памяти, требуемый сохранить массив структур или массив ячеек, зависит не только от того, сколько данных это содержит, но также и от того, как это создается.

Например, возьмите скалярный массив структур S1 наличие полей RG, и B. Каждое поле размера 100 50 требует, чтобы один заголовок массивов описал полную структуру, один заголовок для каждого уникального имени поля и один заголовок на поле для массива структур 1 на 1. Это делает в общей сложности семь заголовков массивов для целой структуры данных:

S1.R(1:100,1:50)
S1.G(1:100,1:50)
S1.B(1:100,1:50)

С другой стороны, возьмите 100 50 массив структур S2 в котором каждый элемент имеет скалярные поля RG, и B. В этом случае вам нужен один заголовок массивов, чтобы описать полную структуру, один для каждого уникального имени поля, и один на поле для каждого из 5 000 элементов структуры, делая в общей сложности 15 004 заголовка массивов для целой структуры данных:

S2(1:100,1:50).R
S2(1:100,1:50).G
S2(1:100,1:50).B

Даже при том, что S1 и S2 содержите тот же объем данных, S1 использование значительно меньше пробела в памяти. Мало того, что меньше памяти требуется, но и существует соответствующее преимущество скорости к использованию S1 формат, также.

См. “Массивы ячеек” и “структуры” под структурами данных и памятью.

Использование памяти, о котором Сообщают, кто Функция.  whos функционируйте отображает объем памяти, использованный любой переменной. Для простоты, whos отчеты только память раньше хранили фактические данные. Это не сообщает об устройстве хранения данных для заголовка массивов, например.

Аргументы функции

MATLAB обрабатывает аргументы, переданные в вызовах функции похожим способом. Когда вы передаете переменную функции, вы на самом деле передаете ссылку на данные, которые представляет переменная. Пока входные данные не изменяется вызванной функцией, переменная в функции вызова и переменная в названной единице функциональности к тому же местоположению в памяти. Если вызванная функция изменяет значение входных данных, то MATLAB делает копию исходного массива в новом месте в памяти, обновления, которые копируют с модифицированным значением, и указывает входную переменную в вызванной функции к этому новому массиву.

В примере ниже, функционируйте myfun изменяет значение массива, переданного в него. MATLAB делает копию в память о массиве указанной A, переменная X наборов как ссылка на этот новый массив, и затем устанавливает одну строку X обнулять. На массив ссылается A остается неизменным:

A = magic(500);
myfun(A);

function myfun(X)
X(400,:) = 0;

Если для функции вызова нужно модифицированное значение массива, это передало myfun, необходимо возвратить обновленный массив как выход вызванной функции, как показано сюда для переменной A:

A = magic(500);
A = myfun(A);
sprintf('The new value of A is %d', A)

function Y = myfun(X)
X(400,:) = 0;
Y = X;

Структуры данных и память

Требования к памяти отличаются для различных типов структур данных MATLAB. Вы можете смочь уменьшать объем памяти, используемый для этих структур путем рассмотрения, как MATLAB хранит их.

Числовые массивы

MATLAB требует 1, 2, 4, или 8 байтов хранить 8-битные, 16-битные, 32-битные, и 64-битные целые числа со знаком и беззнаковое целое, соответственно. Для чисел с плавающей запятой MATLAB использует 4 или 8 байтов для single и double типы. Чтобы сохранить память при работе с числовыми массивами, MathWorks® рекомендует, чтобы вы использовали самый маленький целочисленный или тип с плавающей точкой, который содержит ваши данные без переполнения. Для получения дополнительной информации смотрите Числовые Типы.

Комплексные массивы

MATLAB использует представление хранения с чередованием комплексных чисел, где действительные и мнимые части хранятся вместе в непрерывном виртуальном блоке памяти. Если вы делаете копию комплексного массива, и затем изменяете только действительную или мнимую часть массива, MATLAB создает массив, содержащий и действительные и мнимые части. Для получения дополнительной информации смотрите Поддержку MATLAB Чередованного Комплексного API в MEX-функциях.

Разреженные матрицы

Лучше хранить матрицы значениями, которые являются в основном нулем в разреженном формате. Разреженные матрицы могут использовать меньше памяти и могут также быть быстрее, чтобы управлять, чем полные матрицы. Можно преобразовать полную матрицу в разреженный формат с помощью sparse функция.

Сравните две матрицы 1000 на 1000: X, матрица удваивается с 2/3 ее равных нулю элементов; и Y, разреженная копия X. Следующий пример показывает, что разреженная матрица требует приблизительно вдвое меньше памяти:

whos
  Name      Size                   Bytes  Class

  X      1000x1000               8000000  double array
  Y      1000x1000               4004000  double array (sparse)

Массивы ячеек

В дополнение к хранению данных массивы ячеек требуют, чтобы дополнительная память хранила информацию, описывающую каждую ячейку. Эта информация зарегистрирована в header, и существует один заголовок для каждой ячейки массива. Можно определить объем памяти, требуемый для заголовка массива ячеек путем нахождения количества байтов использованным ячейкой 1 на 1, которая не содержит данных, как показано ниже для 64-битной системы:

C = {[]};      % Empty cell array
whos C

  Name      Size            Bytes  Class    Attributes

  C         1x1               104  cell

Чтобы предсказать размер целого массива ячеек, умножьте размер заголовка на общее количество ячеек в массиве, и затем добавьте в это количество байтов, требуемых для данных, которые вы намереваетесь хранить в массиве:

(header_size x number_of_cells) + data

Например, 10 20 массив ячеек, который содержит 400 байтов данных, потребовал бы 21 200 байтов памяти в 64-битной системе:

(104 x 200) + 400 = 21200

Примечание

В то время как числовые массивы должны храниться в непрерывной памяти, структуры и массивы ячеек не делают.

Пример – Выделение памяти для Массива ячеек.  Это 4 1 массив ячеек записывает фирменный знак, размер экрана, цену и распивочное состояние для трех ноутбуков:

Laptops = {['SuperrrFast 89X', 'ReliablePlus G5', ...
            'UCanA4dIt 140L6']; ...
           [single(17), single(15.4), single(14.1)]; ...
           [2499.99, 1199.99, 499.99]; ...
           [true, true, false]};

В 64-битной системе один только заголовок массива ячеек требует 104 байтов за ячейку:

4 cells * 104 bytes per cell = 416 bytes for the cell array

Вычислите память, требуемую содержать данные в каждой из этих четырех ячеек:

45 characters * 2 bytes per char = 90 bytes
 3 singles * 4 bytes per single = 12 bytes
 3 doubles * 8 bytes per double = 24 bytes
 3 logicals * 1 byte per logical = 3 bytes

90 + 12 + 24 + 3 = 129 bytes for the data

Добавьте эти два, и затем сравните свой результат с размером, возвращенным MATLAB:

416 + 129 = 545 bytes total

whos Laptops
  Name         Size            Bytes  Class    Attributes

  Laptops      4x1               545  cell     

Структуры

В 64-битной системе каждое поле массива структур требует 104-байтового заголовка. Кроме того, каждое уникальное имя поля требует 64-байтового заголовка. Например, структура с одним пустым полем использует 168 байтов (104 байта для поля и 64 байта для имени поля):

S.A = [];
whos S

  Name      Size            Bytes  Class     Attributes

  S         1x1               168  struct     

Чтобы предсказать размер целого массива структур, вычислите общее количество байтов заголовка, и затем добавьте в это количество байтов, требуемых для данных, которые вы намереваетесь хранить в массиве:

number_of_fields x ((number_of_array_elements x field_header_size) + fieldname_header_size) + data

Например, 4 5 структура Clients с полями Address и Phone использование 4 288 байтов только для заголовков:

2 x ((20 x 104) + 64) = 4288 bytes

К той сумме необходимо добавить память, требуемую содержать данные, присвоенные каждому полю. Если вы присваиваете 25 векторов символов Address и 12 векторов символов к Phone в каждом элементе 4 5 Clients массив, вам нужны 1 480 байтов для данных:

(25+12) characters * 2 bytes per char * 20 elements = 1480 bytes

Добавьте два, и вы видите, что целая структура использует 5 768 байтов памяти.

Пример – Выделение памяти для Массива структур.  Вычислите объем памяти, требуемый на 64-битную систему сохранить 6 5 массив структур с этими значениями полей:

A:  5-by-8-by-6 signed 8-bit integer array
B:  1-by-500 single array
C:  30-by-30 unsigned 16-bit integer array
D:  1-by-23 character array

Создайте массив:

A = int8(ones(5,8,6));
B = single(1:500);
C = uint16(magic(30));
D = 'Company Name: MathWorks';

S = struct('f1',A,'f2',B,'f3',C,'f4',D);

for m = 1:6
   for n = 1:5
      S(m,n) = S(1,1);
   end
end

Вычислите объем памяти, требуемый для самой структуры, и затем для данных это содержит:

structure = fields x ((array elements x 104) + 64) =
            4 x ((30 x 104) + 64) = 12,736 bytes

data = (field1 + field2 + field3 + field4) x array elements =
       (240 + 2000 + 1800 + 46) x 30 = 122,580 bytes

Добавьте эти два, и затем сравните свой результат с размером, возвращенным MATLAB:

Total bytes calculated for structure S: 12,736 + 122,580 = 135,316

whos S

  Name      Size             Bytes  Class     Attributes

  S         6x5             135316  struct