Как исправить ошибку «Недостаточно памяти» при переносе и загрузке больших файлов в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При обработке файлов большого размера (от 400 МБ и выше) в файловых базах 1С пользователи и разработчики часто сталкиваются с ошибкой «Недостаточно памяти». При этом на сервере может быть установлено несколько десятков гигабайт оперативной памяти, а файл подкачки и жесткий диск имеют много свободного места. Выясним причину возникновения этой проблемы и подробно разберем варианты ее решения.

Анализ причины возникновения ошибки

Проанализируем ситуацию, которая приводит к аварийному завершению работы процесса 1cv8c.exe. При считывании и передаче крупных файлов происходят следующие процессы:

  1. Ограничение виртуального адресного пространства: В 32-разрядных приложениях максимальный объем виртуальной памяти для одного процесса ограничен 2–3 ГБ. Как только объем задействованной памяти процессом 1cv8c.exe доходит до отметки 2400–2450 МБ, платформа исчерпывает адресное пространство и аварийно завершает работу.
  2. Многократное дублирование данных в ОЗУ: При загрузке файла в объекты типа ДвоичныеДанные или ХранилищеЗначения платформа создает несколько временных копий данных в оперативной памяти (для буферизации, преобразования в Base64 при вызовах между клиентом и сервером и помещения во временное хранилище). В итоге файл размером 500 МБ может потребовать свыше 2 ГБ ОЗУ.
  3. Фрагментация памяти: Из-за фрагментации виртуального адресного пространства платформа не может выделить единый непрерывный блок памяти для размещения массива байтов крупного файла.

Способ 1. Использование 64-разрядного клиента и обновление платформы

Рассмотрим самое простое и эффективное решение. Если вы работаете с 32-разрядным тонким или толстым клиентом, система неизбежно упрется в лимит оперативной памяти процесса.

  1. Установим 64-разрядный клиент 1С (процесс 1cv8c.exe x64). Это снимает жесткое ограничение в 2 ГБ на процесс и позволяет задействовать необходимый объем оперативной памяти сервера или терминала.
  2. Обновим платформу 1С до актуального релиза. В свежих релизах платформы оптимизирована работа с памятью и механизмы передачи двоичных данных.

Способ 2. Переход на потоковую обработку файлов

Разберем вариант оптимизации программного кода, если файл обрабатывается средствами платформы. Вместо считывания всего файла целиком в объект ДвоичныеДанные применим потоковое чтение и запись частями (буферами):


ИмяВходногоФайла = "C:\Files\LargeFile.zip";
ИмяВыходногоФайла = "C:\Files\Copy_LargeFile.zip";

ПотокЧтения = Новый ФайловыйПоток(ИмяВходногоФайла, РежимОткрытияФайла.Открыть);
ПотокЗаписи = Новый ФайловыйПоток(ИмяВыходногоФайла, РежимОткрытияФайла.Создать);

ЧтениеДанных = Новый ЧтениеДанных(ПотокЧтения);
ЗаписьДанных = Новый ЗаписьДанных(ПотокЗаписи);

РазмерБуфера = 1048576; // 1 МБ
Пока НЕ ПотокЧтения.Конец() Цикл
    ДвоичныеДанныеБуфера = ЧтениеДанных.Прочитать(РазмерБуфера);
    ЗаписьДанных.ЗаписатьДвоичныеДанные(ДвоичныеДанныеБуфера);
КонецЦикла;

ЗаписьДанных.Закрыть();
ЧтениеДанных.Закрыть();
ПотокЗаписи.Закрыть();
ПотокЧтения.Закрыть();

Способ 3. Порционная передача через разделение файла

Посмотрим на метод разбиения файла на части фиксированного размера. Если необходимо выгрузить или загрузить файл большого объема, разберем работу функций РазделитьФайл() и ОбъединитьФайлы():


// Разделение файла на фрагменты по 20 МБ
ИмяИсходногоФайла = "C:\Export\BigDataBase.bak";
КаталогЧастей = "C:\Export\TempParts\";
РазмерЧасти = 20 * 1024 * 1024; // 20 МБ

МассивФайловЧастей = РазделитьФайл(ИмяИсходногоФайла, РазмерЧасти, КаталогЧастей);

// Последовательная обработка частей или их передача по одной
// ...

// Последующее объединение частей обратно в один файл
ИмяИтоговогоФайла = "D:\Import\BigDataBase.bak";
ОбъединитьФайлы(МассивФайловЧастей, ИмяИтоговогоФайла);

Способ 4. Настройка хранения файлов в томах в БСП

В файловой базе данные хранятся в файле 1cd, имеющем лимит 4 ГБ на одну таблицу. Хранение крупных файлов непосредственно в базе данных приводит к быстрому разрастанию таблицы и перегрузке памяти при считывании LOB-полей.

Настроим хранение файлов в томах на диске через Библиотеку Стандартных Подсистем (БСП):

  1. Перейдем в раздел Администрирование — Настройки работы с файлами.
  2. Установим флаг Хранить файлы в томах на диске.
  3. Создадим новый том хранения файлов и укажем путь к папке на диске.
  4. Запустим процесс переноса файлов из базы данных в тома хранения. Это существенно снизит нагрузку на оперативную память и файл базы данных.

Способ 5. Своевременная очистка временного хранилища

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

Для принудительного освобождения ресурсов очистим адресное пространство сразу после обработки файла:


// Очистка адресного пространства после работы с файлом
УдалитьИзВременногоХранилища(АдресФайлаВоВременномХранилище);

Применение комплекса этих мер позволяет полностью устранить ошибку «Недостаточно памяти» и обеспечить стабильную работу 1С с файлами любых объемов.

← На главную