Решение ошибок “Нехватка памяти”

Проблема

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

A = rand(1e9);
Requested array exceeds the maximum possible variable size.

По умолчанию MATLAB может использовать до 100% RAM (не включая виртуальную память) вашего компьютера, чтобы выделить память для массивов, и если размер массивов превысил бы тот порог, то MATLAB производит ошибку. Например, этот код пытается создать массив, размер которого превышает максимальный предел размера массивов.

B = rand(1e6);
Requested 1000000x1000000 (7450.6GB) array exceeds maximum array size preference (63.7GB). This might cause MATLAB to become
unresponsive.

Если вы выключаете предел размера массивов в MATLAB Workspace Preferences, пытание создать необоснованно большой массив может заставить MATLAB исчерпывать память, или это может сделать MATLAB или даже ваш компьютер безразличными из-за чрезмерной разбивки на страницы памяти (то есть, переместив страницы памяти между RAM и диском).

B = rand(1e6);
Out of memory.

Возможные решения

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

Примечание

Решения, представленные здесь, характерны для MATLAB. Чтобы оптимизировать эффективность памяти в масштабе всей системы, рассмотрите добавление большей физической памяти (RAM) к вашему компьютеру или внесению изменений на уровне операционной системы.

Очистите переменные, когда больше не необходимый

Сделайте его практикой, чтобы очистить переменные, когда они больше не будут необходимы. Чтобы очистить элементы из памяти, используйте clear функция.

ПреждеПосле
A = rand(1e4);
disp(max(A,[],"all"))
B = rand(1e4);
A = rand(1e4);
disp(max(A,[],"all"))
clear A
B = rand(1e4);

Для получения дополнительной информации см. Стратегии Эффективного использования Памяти.

Используйте соответствующее хранение данных

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

Использование соответствующего числового класса.  Числовой класс, который необходимо использовать, зависит от намеченных действий. В MATLAB, double тип числовых данных по умолчанию и обеспечивает достаточную точность для большинства вычислительных задач:

  • Если вы хотите выполнить сложную математику, такую как линейная алгебра, используйте числа с плавающей запятой в любом с двойной точностью (double) или с одинарной точностью (singleформат. Количества типа single потребуйте меньшей памяти, чем количества типа double, но также представлены меньшей точности.

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

Класс (тип данных)БайтыПоддерживаемые операции
single4Большая часть математики
double8Вся математика
logical1Логические/условные операции
int8, uint81Арифметика и некоторые простые функции
int16, uint162Арифметика и некоторые простые функции
int32, uint324Арифметика и некоторые простые функции
int64, uint648Арифметика и некоторые простые функции

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

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

ПреждеПосле
% S has 15,000 fields (3 fields per array element)
for i = 1:100
    for j = 1:50
        S(i,j).R = 0;  % Each field contains a numeric scalar
        S(i,j).G = 0;
        S(i,j).B = 0;
    end
end
% S has 3 fields 
S.R = zeros(100,50);  % Each field contains a numeric array
S.G = zeros(100,50);
S.B = zeros(100,50);

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

ПреждеПосле
I = eye(1000);
I = speye(1000);

Импортируйте Данные Используя Соответствующий Класс MATLAB.  При чтении данных из двоичного файла с fread, частая ошибка состоит в том, чтобы задать только класс данных в файле а не класс данных использование MATLAB, если это находится в рабочей области. Если вы не задаете класс данных в памяти, MATLAB использует double даже если вы читаете 8-битные значения.

ПреждеПосле
fileID = fopen("large_file_of_uint8s.bin","r"); 
A = fread(fileID,1e3,"uint8"); 
fileID = fopen("large_file_of_uint8s.bin","r"); 
A = fread(fileID,1e3,"uint8=>uint8"); 

Избегайте ненужных копий данных

Чтобы улучшить скорость использования памяти и выполнения, убедитесь, что ваш код не приводит к ненужным копиям данных. Для получения дополнительной информации о решениях в этом разделе, смотрите, Избегают Ненужных Копий Данных и Стратегий Эффективного использования Памяти.

Предотвращение создавать Временные массивы.  Постарайтесь не создавать временные массивы, когда они не будут необходимы. Например, вместо того, чтобы создать массив нулей как временная переменная и затем передать ту переменную функции, используйте одну команду, чтобы сделать обе операции.

ПреждеПосле
A = zeros(1e6,1);
As = single(A);
As = zeros(1e6,1,"single");

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

ПреждеПосле
x = 0;
for k = 2:1000000
   x(k) = x(k-1) + 5;
end
x = zeros(1,1000000);
for k = 2:1000000
   x(k) = x(k-1) + 5;
end

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

Один способ избежать временных копий в вызовах функции состоит в том, чтобы использовать вложенные функции. Вложенная функция совместно использует рабочую область всех внешних функций, таким образом, вы не должны передавать копию переменных в вызове функции. Для получения дополнительной информации смотрите Вложенные функции.

Загрузите только столько данные, сколько вам нужно

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

datastore функция позволяет вам работать с большими наборами данных инкрементно. Хранилища данных полезны любое время, вы хотите загрузить только некоторые фрагменты набора данных в память за один раз.

Чтобы создать datastore, обеспечьте имя файла или директорию, содержащую набор файлов с подобным форматированием. Например, с одним файлом, используйте следующее.

ds = datastore("path/to/file.csv");
Или с набором файлов в папке, используйте следующее.
ds = datastore("path/to/folder/");
Также можно использовать подстановочный символ * выбрать все файлы определенного типа.
ds = datastore("path/to/*.csv");
Хранилища данных поддерживают большое разнообразие форматов файлов (табличные данные, изображения, электронные таблицы, и так далее). Для получения дополнительной информации смотрите, Выбирают Datastore for File Format или Application.

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

FileType Частичная загрузка
Matfile

Загрузите часть переменной путем индексации в объект, который вы создаете с matfile функция. Для получения дополнительной информации смотрите, Сохраняют и Части Загрузки Переменных в MAT-файлах.

Текст

Используйте textscan функционируйте, чтобы получить доступ к частям файла крупного текста путем чтения только выбранных столбцов и строк. Если вы задаете количество строк или повторный номер формата с textscan, MATLAB вычисляет точный объем памяти, требуемый заранее.

Двоичный файл

Можно использовать низкоуровневые функции ввода-вывода двоичного файла, такой как fread, к частям доступа любого файла, который имеет известный формат. Для двоичных файлов неизвестного формата попытайтесь использовать размещение в ОЗУ с memmapfile функция.

Изображение, аудио, видео и HDF

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

Используйте длинные массивы

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

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

    t = tall(A);
    Этот подход позволяет вам работать с большими массивами, которые могут уместиться в памяти, но которые используют слишком много памяти, чтобы допускать копии данных во время вычислений. Например, если у вас есть 8 Гбайт RAM, и матрица на 5 Гбайт, бросая матрицу к длинному массиву позволяет вам выполнить вычисления на матрице, не исчерпывая память. Для примера этого использования смотрите tall.

  • Если у вас есть файл - или основанные на папке данные, можно создать datastore и затем создать высокий массив поверх datastore.

    ds = datastore("path/to/file.csv");
    t = tall(ds);
    Этот подход дает вам полную мощность длинных массивов в MATLAB. Данные могут иметь любое количество строк, и MATLAB не исчерпывает память. И потому что datastore работает и с районами локальных и с удаленных данных, данные, с которыми вы работаете, не должны быть на компьютере, который вы используете, чтобы анализировать их. Смотрите работу с Удаленными данными для получения дополнительной информации.

Чтобы узнать больше о длинных массивах, смотрите Длинные массивы для Данных, которые не помещаются в память.

Используйте память о нескольких машинах

Если у вас есть кластер компьютеров, можно использовать распределенные массивы (требует Parallel Computing Toolbox™) выполнять вычисления с помощью объединенной памяти обо всех машинах в кластере. В зависимости от того, как ваши совпадения данных в памяти, существуют различные способы разделить данные среди рабочих параллельного пула. Для получения дополнительной информации смотрите Распределительные Массивы, чтобы быть Параллельными Рабочим (Parallel Computing Toolbox).

Настройте настройки и настройки

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

Запустите MATLAB Без виртуальной машины Java или Уменьшения Размер Кучи Java.  Если вы любой запуск MATLAB без Java® Программное обеспечение Virtual Machine (JVM™) или уменьшение размер кучи Java, можно увеличить доступную память рабочей области. Чтобы запустить MATLAB без JVM, используйте параметр командной строки -nojvm. Для получения информации о том, как уменьшить размер кучи Java, смотрите Настройки Java Heap Memory.

Используя -nojvm идет со штрафом в этом, вы теряете несколько функций, которые используют JVM, такую как настольные инструменты и графика. Стартовый MATLAB с -nodesktop опция не сохраняет значительного количества памяти.

Настройте Предел Размера Массивов.  Если вы сталкиваетесь с ошибкой при утверждении, что размер массивов превышает максимальную настройку размера массивов, можно настроить этот предел размера массивов в MATLAB. Для получения информации о корректировке предела размера массивов смотрите Рабочую область и Настройки переменной. Это решение полезно, только если массив, который вы хотите создать, превышает текущий максимальный предел размера массивов, но не является слишком большим, чтобы уместиться в памяти. Даже если вы выключаете предел размера массивов, пытание создать необоснованно большой массив может заставить MATLAB исчерпывать память, или это может сделать MATLAB или даже ваш компьютер безразличными из-за чрезмерной разбивки на страницы памяти.

Смотрите также

| | |

Похожие темы