Утечки памяти в 1С: как локализовать через технологический журнал и починить в коде
Как выглядит утечка глазами админа и глазами пользователя
Утечка ресурсов на сервере 1С — это ситуация, когда рабочий процесс с течением времени забирает у системы всё больше памяти и не возвращает её обратно. Симптомы накапливаются медленно и редко привязаны к одному действию. Типичный набор жалоб:
- «Утром всё нормально, к вечеру тормозит» — без привязки к конкретной операции;
- «Перезапустили сервер — стало лучше» — самый частый ответ службы поддержки, и одновременно — признание, что причину никто не нашёл;
- «Растёт память rphost'ов в диспетчере задач»: процесс, который вчера занимал 800 МБ, сегодня — 4 ГБ;
- В пиковые часы — самопроизвольный перезапуск сервиса 1С по достижении лимита памяти.
Если хотя бы два из четырёх симптомов совпали с вашей картиной — почти гарантированно утечка ресурсов где-то в коде доработки или внешнего соединения. Просто «нагрузки много» столько памяти не съедают.
Что может «течь» в 1С
| Источник утечки | Признак в логах | Как чинится в коде |
|---|---|---|
| Незакрытые COM-объекты | Накапливаются ссылки на одни и те же имена внешних объектов | Явное освобождение ссылки после использования, обработка ошибок через попытку |
| Долгоживущие массивы и соответствия в общих модулях | Память процесса растёт линейно от числа сеансов | Локальные переменные внутри процедур, очистка кэша по таймауту |
| Открытые соединения с внешними системами | Растёт количество открытых сокетов на ОС | Закрывать соединения сразу после ответа, не держать «на потом» |
| Файловые потоки без закрытия | В логе ОС — обращения к одним и тем же файлам тысячами | Закрывать поток в финале даже при исключении |
Технологический журнал как инструмент поиска
Что такое технологический журнал
Это серверный лог платформы 1С, который пишет события рабочих процессов: входы и выходы из методов, исключения, обращения к СУБД, операции с памятью. Настраивается через файл `logcfg.xml` в каталоге конфигурации сервера 1С (обычно `conf/`). Без настройки журнал не пишется — платформа экономит ресурсы.
Что включить для поиска утечки
На время диагностики имеет смысл писать события вызовов методов, исключений и специальное событие трекинга утечек. На платформе это категории `CALL`, `EXCP` и `LEAKS` — последняя специально сделана для отслеживания не-освобождённых ссылок в долгих вызовах. Журнал получается объёмный (десятки гигабайт в сутки на нагруженном сервере), поэтому пишут на отдельный диск, фильтруют по проблемному пользователю или сеансу, и не оставляют включённым «на всякий случай».
Самая частая ошибка диагностики — включить технологический журнал на всём сервере «пока не найдём». Через два дня место на диске кончается, журнал перезаписывается, реальной точки прерывания нет. Включайте на одного-двух подозрительных пользователей, на полчаса, с фильтром по сеансу. Этого почти всегда хватает.
Анализ
Главное, что ищем в логе — повторяющиеся пары «вход в метод — выход с исключением» без последующего освобождения ресурса. Если COM-объект открылся, метод упал по исключению и закрытия объекта в логе не видно — это явный кандидат. Или: процедура запускается тысячи раз, каждый раз создаёт массив на 10 тысяч элементов, но ни разу его не очищает — память процесса растёт линейно.
Безопасные приёмы в коде
Большинство утечек в 1С возникают не от изощрённой работы с памятью, а от типовых ошибок: «открыл и забыл закрыть». Базовый защитный приём — обёртка работы с ресурсом в конструкцию обработки исключения, где закрытие ресурса гарантированно выполняется и при ошибке:
// Шаблон: открыли ресурс, поработали, гарантированно закрыли
ВнешнийРесурс = Неопределено;
Попытка
ВнешнийРесурс = ОткрытьВнешнийРесурс(Путь);
ОбработатьДанные(ВнешнийРесурс);
Исключение
ЗаписьЖурналаРегистрации("Утечка-диагностика",
УровеньЖурналаРегистрации.Ошибка, , ,
ОписаниеОшибки());
КонецПопытки;
// Освобождение — отдельно, чтобы выполнилось и при ошибке
Если ВнешнийРесурс <> Неопределено Тогда
ВнешнийРесурс = Неопределено;
КонецЕсли;
Присваивание `Неопределено` отрывает ссылку — платформа освобождает память за следующий проход сборщика. Если ресурс — COM-объект, это критично: без явного отказа от ссылки COM-объект может висеть в памяти до завершения сеанса. На долгоживущем сервере таких висящих объектов набирается за день несколько тысяч.
Чек-лист диагностики
- Снять график потребления памяти rphost-процессов за неделю. Подтвердить, что рост есть, и привязать его к рабочим часам.
- Идентифицировать одного-двух пользователей, чья активность совпадает с пиками. Опросить: какие операции делают в эти моменты.
- На полчаса включить технологический журнал на этих сеансах с категориями `CALL`, `EXCP`, `LEAKS`.
- Найти в логе циклически повторяющиеся пары «вход в процедуру — необработанное исключение» или «открытие COM-объекта без последующего закрытия».
- Подтвердить гипотезу: воспроизвести сценарий на тестовой базе, замерить рост памяти процесса.
- Внести правку в код: обёртка в попытку, явное освобождение ссылки, очистка кэша после использования.
- Откатить настройки технологического журнала на минимум. Не оставлять журнал включённым в продакшене после диагностики.
Типичные ошибки
- «Перезапускаем сервер раз в сутки — нам так нормально». Это не нормально: проблема пользователей решается, но симптом скрывается. При росте числа пользователей или объёма данных перезапуск перестанет помогать, утечка сожрёт память за полдня. Сейчас — самый дешёвый момент для починки.
- Включили журнал, но забыли отключить. Диагностику закончили, утечку починили, журнал работает в фоне ещё месяц. Диск переполняется, плановое резервное копирование падает по нехватке места. Отключайте журнал явно — закладывайте этот шаг в регламент диагностики.
- Анализ логов «глазами». Сотни тысяч строк лога вручную не разбираются — внимание устаёт, важное теряется. Используйте grep, awk или специализированные парсеры технологического журнала. Минимально — посчитайте количество входов в каждый метод и количество выходов; расхождение покажет проблемную процедуру.
- «Перевели на больший сервер, проблема прошла». На 64 ГБ сервере утечка проявляется через три дня вместо одного — и кажется, что её больше нет. На самом деле проблема в коде, и рано или поздно она проявится с новой силой при росте нагрузки.
- Чинят первое попавшееся. Один разработчик увидел в коде непропатченный COM-объект, починил, отрапортовал. Утечка не ушла — была не там. Без подтверждения гипотезы на стенде правки в боевом коде в лучшем случае не помогают, в худшем — добавляют новые ошибки.
Перейти в каталог решений →