Как устранить ошибку нехватки памяти при выгрузке данных из 1С?

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

При выполнении обмена данными или переносе большого массива информации с помощью правил конвертации («Конвертация данных 2.0») разработчики и администраторы 1С часто сталкиваются с аварийным завершением работы программы и системной ошибкой: «Недостаточно памяти». При этом физической оперативной памяти на сервере или рабочей станции может быть более чем достаточно. Разберем детально, почему это происходит и какими способами можно полностью решить данную проблему.

Архитектурные причины возникновения ошибки

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

  1. Ограничение адресного пространства 32-битного процесса. В 32-разрядных приложениях Windows одному пользовательскому процессу (1cv8.exe или рабочему процессу сервера) по умолчанию доступно не более 2 ГБ виртуального адресного пространства. С учетом неизбежной фрагментации памяти процесс аварийно завершается уже при достижении порога потребления в 1.5–1.7 ГБ, даже если на машине установлено 64 или 128 ГБ RAM.
  2. Накопление служебных таблиц в сеансе. Типовая универсальная обработка выгрузки по правилам обмена непрерывно фиксирует в памяти список всех выгруженных объектов для предотвращения дублирования и зацикливаний. При обработке огромных массивов данных граф ссылок разрастается в оперативной памяти в геометрической прогрессии.
  3. Каскадная выгрузка зависимых ссылок. При передаче документов типовые правила часто подтягивают всю цепочку связанных справочников, договоров, спецификаций и движений регистров, удерживая их объекты в контексте выполнения.

Решение 1. Переход на 64-битные компоненты платформы

Самый прямой и надежный способ снять барьер в 2 ГБ — использовать 64-разрядную версию платформы 1С:Предприятие. Рассмотрим этот подход:

  1. Использование 64-битного клиента и сервера. 64-разрядные процессы 1С способны адресовать практически неограниченный объем оперативной памяти, что исключает падение сеанса при обработке XML-файлов размером в сотни мегабайт и гигабайты.
  2. Настройка ключа Large Address Aware (для 32-битных клиентов). Если переход на полноценный 64-битный клиент временно невозможен, в 64-битной ОС Windows 32-битному приложению можно разрешить адресацию до 4 ГБ виртуальной памяти. Для этого исполняемый файл модифицируется системной утилитой:

editbin /LARGEADDRESSAWARE 1cv8.exe

А для 32-разрядных версий операционной системы Windows расширение пользовательского адресного пространства до 3 ГБ выполняется через командную строку администратора:

bcdedit /set IncreaseUserVa 3072

Решение 2. Оптимизация правил обмена в «Конвертации данных»

Выясним причину чрезмерного расхода памяти в самих алгоритмах правил конвертации (КД 2.0) и разберем способы их оптимизации:

  1. Отказ от получения тяжелых объектов целиком. В обработчиках событий («Перед выгрузкой», «При выгрузке») избегайте вызовов метода Ссылка.ПолучитьОбъект(). Получение объекта целиком помещает все его реквизиты и табличные части в кэш сеанса. Используйте прямые запросы к нужным полям.
  2. Своевременное освобождение структур и таблиц. Если в глобальной структуре Параметры или локальных переменных формируются вспомогательные таблицы значений, их необходимо принудительно занулять сразу после использования:

Параметры.ТаблицаЦен = Неопределено;
ПромежуточнаяВыборка = Неопределено;
  1. Отключение выгрузки объектов по ссылкам. В настройках обработки выгрузки или для конкретных правил конвертации объектов (ПКО) включите флаг «Не выгружать объекты по ссылкам», если эти данные передаются отдельными правилами.
  2. Исключение движений документов. Если в информационной базе-приемнике настроено автоматическое проведение документов при загрузке, отключите выгрузку наборов записей движений документов по регистрам, чтобы не раздувать XML-файл.

Решение 3. Порционная выгрузка данных и очистка памяти сеанса

Если изменить правила или конфигурацию платформы нельзя, применим методику дробления выгрузки:

  1. Разбиение периода на более мелкие интервалы. Как показывает практика, при уменьшении периода выборки (например, выгрузка по декадам или неделям вместо месяца) пиковое потребление памяти не превышает критический порог в 1.5 ГБ.
  2. Пакетный запуск сеансов по расписанию. Настройте пакетный запуск 1С в командном режиме через скрипт (батник или PowerShell). Выгрузка каждого отдельного интервала времени в новом сеансе 1С гарантирует 100% освобождение оперативной памяти операционной системой после закрытия каждого процесса.

Решение 4. Потоковая запись данных через ЗаписьXML

Рассмотрим пример создания собственной быстрой выгрузки без накопления массивов объектов в памяти. Потоковая запись с помощью объекта ЗаписьXML сразу сбрасывает данные на диск:


Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Exchange\ExportData.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Данные");

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Ссылка,
    |   Номер,
    |   Дата,
    |   СуммаДокумента
    |ИЗ
    |   Документ.РеализацияТоваровУслуг
    |ГДЕ
    |   Дата МЕЖДУ &ДатаНачала И &ДатаОкончания";

Запрос.УстановитьПараметр("ДатаНачала", НачалоПериода);
Запрос.УстановитьПараметр("ДатаОкончания", КонецПериода);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Запись.ЗаписатьНачалоЭлемента("Документ");
    Запись.ЗаписатьАтрибут("Номер", Строка(Выборка.Номер));
    Запись.ЗаписатьАтрибут("Дата", Формат(Выборка.Дата, "ДФ=yyyy-MM-ddTHH:mm:ss"));
    Запись.ЗаписатьАтрибут("Сумма", XMLСтрока(Выборка.СуммаДокумента));
    Запись.ЗаписатьКонецЭлемента();
КонецЦикла;

Запись.ЗаписатьКонецЭлемента(); // Данные
Запись.Закрыть();

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

← На главную