JEP 345: NUMA-Aware Memory Allocation for G1
Выделение памяти с учётом NUMA для G1
| Ответственный | Sangheon Kim |
| Тип | Feature |
| Область | JDK |
| Статус | Closed / Delivered |
| Выпуск | 14 |
| Компонент | hotspot / gc |
| Обсуждение | hotspot dash gc dash dev at openjdk dot java dot net |
| Трудоёмкость | M |
| Длительность | M |
| Duplicates | JEP 157: G1 GC: NUMA-Aware Allocation |
| Рецензенты | Mikael Vidstedt, Stefan Johansson, Thomas Schatzl |
| Одобрен | Mikael Vidstedt |
| Создан | 2018/09/06 22:46 |
| Обновлён | 2020/02/27 21:46 |
| Задача | 8210473 |
Аннотация
Повысить производительность G1 на больших машинах за счёт выделения памяти с учётом NUMA.
Что не является целью
- Реализация поддержки NUMA в сборщиках мусора, отличных от G1, не является целью.
- Поддержка операционных систем, отличных от Linux, не является целью.
- Не является целью добавлять учёт NUMA в другие части G1, такие как перехват задач из очередей (task queue stealing), remembered sets или refinement.
Мотивация
В современных многопроцессорных машинах всё чаще используется неоднородный доступ к памяти (non-uniform memory access, NUMA): память находится на разном расстоянии от разных сокетов или ядер. Обращения к памяти между сокетами различаются по производительности: доступ к более удалённым сокетам, как правило, имеет бо́льшую задержку.
Параллельный сборщик мусора, который включается флагом -XX:+UseParallelGC, учитывает NUMA уже много лет. Это помогло повысить производительность конфигураций, в которых одна JVM работает на нескольких сокетах. Другие сборщики мусора HotSpot этой возможности не имели, поэтому не могли использовать такое вертикальное масштабирование на несколько сокетов с NUMA. В частности, крупные корпоративные приложения обычно работают с большой кучей на нескольких сокетах, но при этом хотят сохранить преимущество в управляемости, которое даёт работа в одной JVM. Пользователи сборщика мусора G1 всё чаще упираются в это ограничение масштабирования.
Описание
Куча G1 организована как набор регионов фиксированного размера. Обычно регион — это набор физических страниц, хотя при использовании больших страниц (через -XX:+UseLargePages) одну физическую страницу могут составлять несколько регионов.
Если указан параметр +XX:+UseNUMA, то при инициализации JVM регионы будут равномерно распределены по всем доступным узлам NUMA.
Закрепление узла NUMA за каждым регионом в самом начале несколько негибко, но это можно смягчить следующими улучшениями. Чтобы выделить новый объект для потока-мутатора, G1 может потребоваться выделить новый регион. При этом G1 будет в первую очередь выбирать свободный регион на том узле NUMA, к которому привязан текущий поток, чтобы объект оставался на том же узле NUMA в молодом поколении. Если при выделении региона для мутатора на том же узле NUMA нет свободного региона, G1 запустит сборку мусора. Альтернативная идея, которую предстоит оценить, — искать свободные регионы на других узлах NUMA в порядке удалённости, начиная с ближайшего узла NUMA.
Мы не будем пытаться сохранять объекты на том же узле NUMA в старом поколении.
Humongous-регионы (регионы для очень больших объектов) исключены из этой политики выделения. Для этих регионов мы не будем делать ничего особенного.
Тестирование
Существующие тесты с параметром -XX:+UseNUMA должны выявить любые проблемы с корректностью. Мы предполагаем, что для тестирования используется оборудование с NUMA.
Когда выделение памяти с учётом NUMA выключено, производительность не должна отличаться от исходного кода.
Риски и допущения
Мы предполагаем, что к большинству короткоживущих объектов часто обращается поток, который их выделил. Это безусловно верно для большинства короткоживущих объектов в большинстве объектно-ориентированных программ. Однако есть программы, для которых это допущение не вполне выполняется, поэтому в некоторых случаях возможно снижение производительности. Кроме того, выигрыш зависит ещё и от сочетания двух факторов: насколько выражена NUMA-архитектура нижележащей системы и как часто потоки на таких системах переносятся между узлами NUMA, особенно при высокой нагрузке.