Многие системные администраторы и специалисты по внедрению столкнулись с весьма неприятной ситуацией: после штатного обновления платформы 1С с версий 8.3.10 на релизы 8.3.11, 8.3.12 или 8.3.13 серверы под управлением устаревших операционных систем (Windows Server 2003, Windows XP) начинают катастрофически тормозить. Загрузка процессора достигает 99-100%, интерфейс зависает, а выполнение даже самых тривиальных операций занимает неприемлемо долгое время. При этом на современных ОС, таких как Windows 10 или Windows Server 2016, аналогичные базы работают без каких-либо нареканий.
Давайте подробно разберем эту проблему, проанализируем причины такого поведения системы и выясним, как можно локализовать и устранить эти «тормоза», если апгрейд серверного парка в данный момент невозможен.
Для начала проанализируем ситуацию с помощью профилировщика. Если мы возьмем простой инструмент для анализа использования CPU (например, Very Sleepy) и подключимся к процессу 1С во время зависаний, мы увидим интересную картину. Окажется, что 99% процессорного времени «съедает» системная функция malloc, вызываемая из библиотеки ядра платформы nuke83.dll.
Функция malloc отвечает за выделение памяти. В платформе 1С постоянно создаются и удаляются миллионы мелких объектов, строк и структур. Почему же выделение памяти вдруг стало узким местом? Чтобы ответить на этот вопрос, рассмотрим архитектурные изменения, которые произошли в релизах платформы, начиная с 8.3.11.
Разберем по шагам, что изменилось внутри платформы 1С. До версии 8.3.10 включительно разработчики собирали платформу с использованием сторонней библиотеки C++ под названием STLport. Главной особенностью STLport было то, что она имела собственную встроенную реализацию «кучи» (менеджера памяти). Эта реализация работала автономно от операционной системы и была оптимизирована под частые запросы мелких блоков памяти.
Начиная с версий 8.3.11–8.3.13 разработчики фирмы «1С» перевели платформу на современный компилятор и стандартную библиотеку C++ (Standard Template Library) от Microsoft. С этого момента платформа перестала управлять памятью самостоятельно и начала напрямую запрашивать её у операционной системы, транслируя запросы в системные вызовы. Теперь за каждый выделенный байт отвечает стандартный менеджер памяти Windows. И вот здесь кроется главный конфликт со старыми операционными системами.
Проанализируем, как работает стандартная куча (NT Heap) в Windows Server 2003. Когда программа запрашивает миллионы мелких блоков памяти и затем освобождает их, память начинает сильно фрагментироваться — превращается в «швейцарский сыр» с мелкими пустотами. Аллокатор ОС начинает тратить гигантское количество тактов процессора на поиск свободного фрагмента нужного размера среди этого хаоса. Именно это мы и видим в профилировщике как 99% загрузку на вызовах malloc.
Почему же на новых ОС (начиная с Windows Vista, Windows 7, Windows Server 2008) тормозов нет? Дело в том, что в них Microsoft глубоко интегрировала алгоритм LFH (Low Fragmentation Heap — куча с низкой фрагментацией). Это специальный front-end аллокатор, который кардинально ускоряет работу с мелкими блоками памяти (до 16 Кб) и предотвращает её деградацию. В новых ОС механизм LFH включен по умолчанию для всех приложений, поэтому миллионы вызовов malloc обрабатываются моментально и незаметно для процессора.
В Windows XP и Windows Server 2003 этот механизм присутствует, но по умолчанию не активирован для стандартной кучи, с которой теперь работает 1С.
Посмотрим на практические способы, которые помогут вернуть платформе 1С работоспособность. Разработчики 1С не считают данную ситуацию багом, так как поддержка ОС поколения XP/2003 официально прекращена самой компанией Microsoft. Поэтому исправлять архитектуру платформы никто не будет, и решать задачу придется силами системных администраторов.
Если мы не можем обновить операционную систему, давайте попробуем заставить Windows 2003 использовать современный механизм работы с памятью для процессов 1С. Для этого нам понадобится системная утилита GFlags (Global Flags), которая входит в пакет Microsoft Debugging Tools for Windows.
Вам необходимо прописать флаги для следующих процессов: 1cv8.exe, 1cv8c.exe, rphost.exe, rmngr.exe, ragent.exe. После применения настроек через GFlags обязательно перезагрузите сервер. Практика показывает, что принудительное включение Low Fragmentation Heap способно существенно сгладить или полностью устранить тормоза при вызовах malloc.
Если манипуляции с GFlags не дали желаемого эффекта из-за особенностей серверного железа, самым надежным и проверенным способом остается использование последней стабильной ветки. Мы рекомендуем зафиксировать версию платформы на релизе 8.3.10.x.
В ветке 8.3.10 все еще используется библиотека STLport со своей независимой кучей. Установка этой версии полностью снимет проблему 100% загрузки процессора. Главный минус этого подхода — невозможность обновления конфигураций (например, 1С:Бухгалтерии), которые могут потребовать более новых возможностей платформы в будущем.
Рассмотрим интересный обходной путь, который успешно протестирован в реальных условиях. Если ваш сервер работает под управлением «железной» Windows Server 2003, вы можете развернуть на нем гипервизор и установить внутрь виртуальную машину с более современной операционной системой, например, Windows 7 или Windows Server 2008 R2 (если позволяет объем оперативной памяти).
Парадоксально, но 1С внутри виртуальной машины с Windows 7 (где алгоритм LFH работает «из коробки») будет работать на порядок быстрее, чем на хостовой Windows Server 2003, даже с учетом неизбежного оверхеда, который создает виртуализация.
Мы выяснили причину резкого падения производительности 1С версий 8.3.11 и выше на старых операционных системах. Переход платформы на системный менеджер памяти Microsoft вскрыл архитектурную слабость устаревших ОС при работе с высокой фрагментацией (отсутствие дефолтного LFH). Чтобы обеспечить стабильную работу базы данных и комфорт пользователей, вам потребуется либо принудительно включить LFH через системные флаги, либо использовать виртуализацию, либо отказаться от обновления платформы выше стабильной ветки 8.3.10.