Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

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

1C_STREAM_OUT_OF_MEMORY 1С:Предприятие и СУБД

Гайд 1С: Тюнинг работы с большими массивами данных через ПотокВПамяти

Обновлено: 26.08.2026 · Официальная документация ↗

При обработке тяжелых выгрузок, сериализации XML/JSON или парсинге бинарных файлов наблюдаются следующие проблемы:

  • Резкий рост потребления оперативной памяти рабочим процессом rphost вплоть до аварийного перезапуска по превышению лимита.
  • Исключение Недостаточно памяти (Out of Memory) при конкатенации длинных строк или записи в промежуточный буфер.
  • Длительная блокировка серверного контекста и деградация производительности соседних сеансов.
  • Высокая нагрузка на дисковую подсистему при постоянной записи временных файлов на диск.

1. Переход от строковых буферов к объекту ПотокВПамяти

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

// Оптимизированный алгоритм записи JSON в поток
Поток = Новый ПотокВПамяти();
Запись = Новый ЗаписьJSON;
Запись.ОткрытьПоток(Поток, Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет));

Запись.ЗаписатьНачалоМассива();
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    ЗаписатьJSON(Запись, Новый Структура("Код,Наименование", Выборка.Код, Выборка.Наименование));
КонецЦикла;
Запись.ЗаписатьКонецМассива();
Запись.Закрыть();

// Получение двоичных данных без строковой десериализации
Поток.ТекущаяПозиция = 0;
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();

2. Потоковое чтение и сжатие на лету

Для минимизации размера буфера передавайте поток напрямую в СжатиеДанных или используйте буферизованные потоки чтения (ПотокСБуферизацией):

ПотокДляЧтения = Новый ПотокСБуферизацией(Поток, 65536); // Чтение блоками по 64 КБ
ЧтениеТекста = Новый ЧтениеТекста;
ЧтениеТекста.ОткрытьПоток(ПотокДляЧтения, КодировкаТекста.UTF8);

3. Очистка ресурсов

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

💡 Практика специалистов: При работе с потоками более 500 МБ в 64-битном кластере 1С на платформе Linux контролируйте параметр sysctl vm.max_map_count, чтобы процесс rphost не был аварийно остановлен ядром из-за исчерпания дескрипторов mmap.

Частые вопросы (FAQ)

В чем главное преимущество ПотокВПамяти перед временными файлами на диске?

ПотокВПамяти исключает задержки дискового ввода-вывода (IOPS/await) и блокировки файловой системы ОС, работая напрямую в RAM рабочего процесса rphost с максимальной скоростью шины памяти.

Каков максимальный объем данных, который можно поместить в ПотокВПамяти?

Теоретический предел ограничен разрядностью процесса (для 64-битного rphost ограничение упирается в доступную виртуальную память и лимиты кластера memoryLimit).

Как избежать фрагментации памяти при частой работе с большими потоками?

Используйте фиксированный размер внутреннего буфера при создании ПотокСБуферизацией и своевременно закрывайте потоки через метод Закрыть(), чтобы сборщик мусора платформы мог повторно использовать страницы памяти.

Можно ли передавать ПотокВПамяти между клиентом и сервером?

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

Полезные материалы
Рекомендуем