При настройке мониторинга производительности сервера 1С специалисты часто сталкиваются с ситуацией, когда графики различных счетчиков памяти ведут себя по-разному. Особенно много вопросов вызывает поведение счетчика \Process(rphost)\Private Bytes, который может демонстрировать резкие пики и падения, в то время как \Process(rphost)\Virtual Bytes и \Memory\Available Bytes остаются относительно стабильными. Разберемся, почему это происходит, как правильно интерпретировать эти показатели и какими способами можно воспроизвести подобное поведение для тестирования системы.
Для начала проанализируем, что именно измеряют эти счетчики. Разница в их поведении обусловлена механизмами управления памятью в операционной системе Windows, в частности, процессами резервирования (Reservation) и выделения (Commitment) памяти.
Virtual Bytes — это общий объем виртуального адресного пространства, который процесс зарезервировал для себя. Важно понимать, что в 64-битных системах процесс может сразу «застолбить» огромные диапазоны адресов (терабайты), которые фактически не подкреплены ни физической оперативной памятью (RAM), ни файлом подкачки. Поскольку адресное пространство в 64-битных системах практически не ограничено, Virtual Bytes часто выглядит как прямая горизонтальная линия. Если процесс уже зарезервировал большой кусок адресов ранее, то при реальном выделении памяти под данные значение этого счетчика не изменится.
Private Bytes — это память, которая была «закоммичена» (Committed). Это объем памяти, под который операционная система обязана выделить реальное место либо в физической ОЗУ, либо в файле подкачки. Этот показатель относится только к конкретному процессу и не включает в себя разделяемую (shared) память. Именно поэтому Private Bytes является наиболее чувствительным индикатором того, сколько памяти реально потребляет ваш код в текущий момент.
Таким образом, ситуация, когда Private Bytes резко растет, а Virtual Bytes остается ровным, означает следующее: процесс rphost начал использовать (закоммитил) те адреса, которые были зарезервированы им заранее. Это нормальное поведение для современных высоконагруженных приложений.
Рассмотрим подробнее, какие именно действия в коде 1С приводят к резкому «взрывному» выделению приватной памяти. Как правило, это операции, связанные с обработкой больших массивов данных в оперативной памяти сервера.
Private Bytes стремительно растет; как только объект уничтожается (например, данные переданы в HTTP-ответ), память освобождается.ТекстовыйДокумент, когда файл загружается в память целиком методом Прочитать(), или чтение XML без использования последовательного чтения (через объектную модель), мгновенно нагружает процесс rphost.ТаблицуЗначений и затем выполняете метод ТЗ.Сортировать() или ТЗ.Свернуть(), 1С создает временные индексы и копии данных в памяти процесса.Для тестирования мониторинга или подготовки к экзаменам (например, «1С:Эксперт») нам часто нужно искусственно создать нагрузку. Проанализируем пример кода, который создает резкий скачок Private Bytes за счет работы с временными структурами данных. Один из эффективных способов — работа с запросом к таблицам, содержащим бинарные данные (например, хранилища файлов), и последующая бессмысленная обработка результата в памяти.
Рассмотрим пример кода:
// Создаем запрос к таблице с потенциально большими данными (например, присоединенные файлы)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 5000
| Файлы.ДанныеФайла КАК Данные
|ИЗ
| Справочник.ПрисоединенныеФайлы КАК Файлы";
// Выгружаем результат в таблицу значений. В этот момент Private Bytes начнет расти.
Результат = Запрос.Выполнить().Выгрузить();
// Чтобы пик был заметным и "плавным" при падении, имитируем обработку
Пока Результат.Количество() > 0 Цикл
// Удаляем по одной строке, чтобы память освобождалась постепенно
Результат.Удалить(0);
// Если нужно замедлить падение графика для наглядности,
// можно добавить небольшую паузу (в реальном коде так не делать!)
КонецЦикла;
Другой способ воспроизведения — создание «разреженной» таблицы значений с огромным количеством колонок и строк:
ТЗ = Новый ТаблицаЗначений;
Для НомерКолонки = 1 По 500 Цикл
ТЗ.Колонки.Добавить("Колонка" + НомерКолонки);
КонецЦикла;
Для НомерСтроки = 1 По 10000 Цикл
НоваяСтрока = ТЗ.Добавить();
Для НомерКолонки = 0 По 499 Цикл
НоваяСтрока[НомерКолонки] = "Тестовая строка данных для заполнения памяти " + НомерСтроки;
КонецЦикла;
КонецЦикла;
// После заполнения очищаем
ТЗ.Очистить();
Выясним, могут ли настройки в консоли администрирования кластера влиять на то, как мы видим эти графики. На самом деле, настройки кластера не влияют на сам механизм выделения памяти (это делает платформа через API операционной системы), но они определяют «судьбу» процесса при достижении определенных порогов.
Разберем ключевые параметры:
Private Bytes процесса rphost превысит этот порог, кластер пометит процесс как неисправный.Private Bytes кратковременный (меньше этого интервала), кластер не убьет процесс. Вероятно, именно такие кратковременные всплески вы и наблюдаете на графиках мониторинга.Проанализируем, как использовать полученные знания для обоснования проблем с памятью в реальных условиях или на аттестации. При изучении графиков недостаточно смотреть только на форму кривой; важно анализировать статистические показатели.
1. Пиковая нагрузка против утечки. Если после резкого скачка график Private Bytes возвращается к исходному значению — это признак неоптимального кода (разовое потребление). Если же график ступенчато растет и не возвращается назад — мы имеем дело с классической утечкой памяти (Memory Leak).
2. Использование средних и максимальных значений. Если вы видите резкий пик только по одному счетчику, используйте разницу между Average (средним) и Maximum (максимальным). Если максимум в несколько раз превышает среднее значение, это серьезный аргумент в пользу того, что система нестабильна. При одновременном запуске такой операции несколькими пользователями сервер может исчерпать ресурсы и «упасть».
3. Взаимосвязь со счетчиком Available Bytes. Если Private Bytes скачет вверх, а Available Bytes (свободная память в системе) при этом практически не изменяется, это может означать, что объем скачка (например, 500 Мб) слишком мал относительно общего объема ОЗУ сервера (например, 128 Гб), чтобы его можно было визуально различить на общем графике. В этом случае всегда доверяйте счетчику конкретного процесса (rphost).
Таким образом, резкие скачки Private Bytes — это основной сигнал для программиста о том, что в системе выполняются тяжелые операции с данными «в памяти». Понимая физику процесса резервирования и выделения адресов в Windows, вы сможете легко обосновать причины такого поведения и оптимизировать код там, где это действительно необходимо.