При длительной автоматической обработке большого объема данных (например, при групповом формировании PDF-документов с файлами изображений) разработчики 1С часто сталкиваются с быстрым ростом потребляемой оперативной памяти. Процесс платформы начинает занимать гигабайты ОЗУ, и обычное присвоение переменным значения Неопределено или очистка объектов не приводит к мгновенному возврату памяти операционной системе. Разберем, почему так происходит, как устроена работа с памятью в 1С и какими способами можно эффективно решить эту проблему.
Проанализируем механизмы работы платформы 1С с графическими ресурсами и памятью контекста:
ТабДок = Неопределено лишь сбрасывают ссылку на объект, но менеджер памяти среды выполнения не обязан мгновенно возвращать выделенные блоки памяти операционной системе, сохраняя их в резерве процесса.ТабличныйДокумент и содержащиеся в нем картинки, удерживается в рамках единого сеансового контекста (формы, модуля или сеанса пользователя) до момента завершения работы этого контекста или закрытия формы-владельца.Самый надежный способ очистки памяти в 1С — это вынос ресурсоемкой операции во временный процесс или отдельный сеанс. Когда фоновое задание завершает свою работу, платформа полностью завершает соответствующий рабочий процесс сеанса, и операционная система гарантированно забирает всю выделенную ОЗУ.
Рассмотрим пример организации обработки пачки файлов через фоновое задание:
// Вызов формирования PDF порциями из основного кода
ПараметрыПроцедуры = Новый Массив;
ПараметрыПроцедуры.Добавить(МассивФайловДляОбработки);
// Запускаем фоновое задание, которое выполнит работу в отдельном сеансе
ФоновоеЗадание = ФоновыеЗадания.Выполнить("МойОбщийМодуль.СформироватьПакетPDF", ПараметрыПроцедуры);
ФоновоеЗадание.ОжидатьЗавершения();
После завершения работы процедуры СформироватьПакетPDF сеанс фонового задания закрывается, и память целиком освобождается.
Если фоновые задания по какой-то причине не подходят, аналогичную изоляцию памяти можно реализовать путем запуска автономного сеанса 1С или внешнего приложения через команду ЗапуститьПриложение. Обрабатывая файлы небольшими порциями в автоматически закрывающемся внешнем процессе, мы предотвратим накопление ОЗУ в основном сеансе пользователя.
В современных версиях платформы разработчикам доступны специализированные объекты ЗаписьPDF и ДокументPDF, а также объект ОбрабатываемаяКартинка для сжатия изображений до нужного разрешения (например, 150 DPI) перед их сохранением. Это позволяет генерировать файлы PDF напрямую, обходя громоздкий механизм объекта ТабличныйДокумент.
Посмотрим на пример предварительной оптимизации картинки перед добавлением:
// Оптимизация разрешения изображения перед формированием документа
ИсходнаяКартинка = Новый Картинка("C:\Images\scan.jpg");
Обработка = Новый ОбрабатываемаяКартинка(ИсходнаяКартинка);
Обработка.УстановитьРазрешение(150, 150);
ОптимизированнаяКартинка = Обработка.ПолучитьКартинку();
В 32-разрядных клиентах 1С существует жесткое ограничение адресного пространства (около 2–3 ГБ на процесс). Если объем одновременно обрабатываемой графики превышает этот предел, приложение аварийно завершается с ошибкой «Нехватка памяти». Использование 64-битной версии клиенто-серверной платформы 1С позволяет снять лимит адресного пространства, давая системе возможность корректно обрабатывать больший объем данных без сбоев.