В практике администрирования высоконагруженных систем на базе 1С:Предприятие часто встречается ситуация, когда процесс 1cv8.exe начинает бесконтрольно потреблять оперативную память. Особенно остро эта проблема стоит при использовании "толстого клиента" и обычных форм (например, в конфигурациях "Управление торговлей 10.3", "Управление производственным предприятием 1.3"). В рамках этой статьи мы подробно разберем причины этого явления, проанализируем архитектурные особенности платформы и рассмотрим комплекс мер по устранению утечек памяти без необходимости полной перезагрузки сервера.
Рассмотрим типичную ситуацию: имеется мощный терминальный сервер (например, Windows Server 2019 с 384 ГБ RAM), к которому подключены сотни пользователей. Со временем, даже если пользователи не выполняют активных действий, потребление памяти каждым процессом 1cv8.exe растет, достигая 1-2 ГБ на один сеанс. Суммарно это приводит к полному исчерпанию ресурсов сервера.
Основные симптомы:
Чтобы эффективно бороться с проблемой, разберемся в механике работы памяти в связке Windows + 1С. Здесь действуют несколько факторов.
1. Утечки GDI-объектов и особенности обычных форм
В отличие от управляемых форм, обычные формы в толстом клиенте активно используют графические ресурсы Windows (GDI Objects). Каждый элемент управления (кнопка, поле ввода, таблица) — это системный объект. При активной работе, открытии множества окон или формировании отчетов количество этих объектов растет. Если разработчик или платформа некорректно освобождают дескрипторы, память, выделенная под них, не возвращается в общий пул.
2. Кэширование метаданных и глобальные переменные
Толстый клиент кэширует структуру метаданных (справочники, документы) локально в памяти процесса для ускорения работы. В старых конфигурациях часто используются глобальные модули с переменными, которые инициализируются при старте и живут до конца сеанса. Это приводит к накоплению данных, которые никогда не очищаются.
3. Поведение диспетчера памяти Windows (Working Set)
Операционная система Windows Server стремится кэшировать данные приложений в RAM, пока она свободна. Это называется "Working Set" (рабочий набор). Даже если 1С освободила память внутри себя (Logical Memory), ОС может не забрать эти страницы физической памяти обратно, пока не возникнет дефицит ресурсов. Это создает иллюзию утечки, хотя фактически память просто зарезервирована "на всякий случай".
Первый и самый надежный рубеж обороны — это принудительное завершение "зависших" сеансов. Пользователи часто путают закрытие программы и отключение от удаленного рабочего стола.
Мы рекомендуем настроить групповые политики (GPO) на сервере следующим образом:
Это гарантирует, что процессы 1cv8.exe будут убиты системой, и память освободится, даже если пользователь забыл выйти из программы.
Если административный сброс сессий не подходит (например, из-за длительных фоновых операций), можно использовать механизм принудительного "обрезки" рабочего набора памяти (Working Set Trimming). Существует системная функция Windows API EmptyWorkingSet.
Мы можем реализовать скрипт (например, на PowerShell), который будет периодически обращаться к процессам 1С и заставлять их сбрасывать неиспользуемые страницы памяти в файл подкачки или освобождать их.
Логика работы скрипта:
1cv8.Такой подход позволяет визуально освободить гигабайты оперативной памяти без завершения работы пользователей. Однако стоит помнить, что если пользователю резко понадобятся выгруженные данные, они будут подгружаться с диска, что может вызвать кратковременные задержки.
Разберем методы, которые можно применить внутри конфигурации, чтобы заставить клиент вести себя "скромнее".
1. Использование обработчика ожидания для перезапуска
Так как проблема имеет накопительный характер, эффективным методом является плановый перезапуск клиента. Мы можем внедрить в конфигурацию (например, в модуль обычного приложения) механизм, который будет отслеживать время работы сеанса.
Пример логики реализации:
Процедура ПриНачалеРаботыСистемы()
// Устанавливаем проверку времени работы каждые 15 минут
ПодключитьОбработчикОжидания("ПроверкаВремениСеанса", 900);
КонецПроцедуры
Процедура ПроверкаВремениСеанса() Экспорт
ВремяРаботы = ТекущаяДата() - глДатаЗапускаСеанса; // глДатаЗапускаСеанса должна быть инициализирована при старте
// Если сеанс длится более 20 часов
Если ВремяРаботы > 72000 Тогда
// Проверяем, не запущена ли длительная операция
Если Не ЕстьАктивныеФоновыеПроцессы() Тогда
ЗавершитьРаботуСистемы(Ложь, Истина); // Перезапустить систему
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот код мягко перезагрузит клиент 1С у пользователя, сбросив накопленные утечки и GDI-объекты.
2. Борьба с COM-объектами
Проанализируйте код вашей конфигурации на предмет использования COM-объектов (Excel, Word, компоненты драйверов). В 1С версии 8 крайне важно явно освобождать память после использования внешних объектов.
Если вы создаете объект:
Эксель = Новый COMОбъект("Excel.Application");
// ... какие-то действия
Обязательно завершайте работу с ним:
Эксель.Quit();
Эксель = Неопределено;
Если не присвоить переменной значение Неопределено, ссылка на COM-объект может остаться в памяти процесса до самого закрытия 1С.
Если программные методы не дают нужного эффекта из-за специфики "кривого" кода старой конфигурации, целесообразно разделить нагрузку.
Попробуйте добавить параметр /ClearCache в строку запуска 1С для пользователей терминала. Хотя этот ключ предназначен для очистки кэша метаданных при изменениях конфигурации, в некоторых случаях его использование при каждом запуске предотвращает использование поврежденных или раздутых временных файлов, что косвенно снижает потребление памяти.
Утечка памяти в толстом клиенте на обычных формах — это системная проблема, которую сложно решить одной "галочкой". Мы рекомендуем использовать комбинированный подход:
ОбработчикОжидания.Working Set процессов в периоды пиковой нагрузки.