AMD EPYC және Java 21 Generational ZGC: миллисекундтық кідірісті жеңу
1. 128 ГБ жады жағдайындағы G1GC кемшіліктері
Spigot пен Paper әкімшілері көп жылдар бойы Aikar жалаушаларына сүйеніп G1GC (Garbage-First Garbage Collector) пайдаланып келді. Алайда G1GC көлемі 16–32 ГБ жадыға дейін ғана оңтайлы.
Біздің ALA-CORE-01 түйінімізде әлем чанктарын, Folia аймақтарын және 500-ден астам ойыншының пакеттік ағынын ұстап тұру үшін JVM процесіне 96 ГБ жады бөлінген. Мұндай үлкен кеңістікте G1GC ескі ұрпақты (Old Generation) жинау кезінде «Stop-the-World» фазасына түсіп, серверді 0.3-0.5 секундқа қатырып тастайтын.
2. Generational ZGC қалай жұмыс істейді? (JEP 439)
Java 21-де ресми түрде шыққан Generational ZGC жадыны жас (Young) және кәрі (Old) буындарға бөледі. ZGC жадыны тазалау мен нысандарды жылжыту жұмыстарын ойын процесіне кедергі жасамай, фондық ағындарда орындайды.
Барлық жады сілтемелеріндегі өзгерістерді қадағалау үшін ZGC аппараттық деңгейдегі Load Barrier (жүктеу кедергісі) алгоритмін қолданады. Бұл дегеніміз — тіпті 100 ГБ жады толса да, ойыншылардың фреймтаймы мен TPS ешбір микросекундқа тоқтамайды.
3. AMD EPYC NUMA және Transparent Huge Pages
AMD EPYC 9654 процессоры бірнеше жеке есептеу чиплеттерінен (CCD) тұрады. Жүйе жадысына кідіріссіз қол жеткізу үшін Linux ядросында numactl --interleave=all параметрі арқылы жады адрестерін барлық жады арналарына біркелкі шашу қажет.
Сонымен қатар, 2 МБ-тық үлкен парақтарды (HugePages) қосу процессордың TLB кэшін босатып, жады операцияларының өнімділігін 12%-ға арттырады.
java -Xms96G -Xmx96G \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+AlwaysPreTouch \
-XX:+UseNUMA \
-XX:AllocatePrefetchStyle=3 \
-XX:LargePageSizeInBytes=2m \
-XX:+UseLargePages \
-XX:-OmitStackTraceInFastThrow \
-XX:+UseStringDeduplication \
-Dsun.rmi.dgc.server.gcInterval=2147483646 \
-Dcom.sun.management.jmxremote=false \
-jar folia-1.21.4.jar --nogui
4. Өндірістік GC лагтарын салыстыру бенчмаркі
Серверде 450 ойыншы бір уақытта белсенді қимылдап, PvP жарысы мен динамит жарылыстары өтіп жатқан 4 сағаттық стресс-сынақ кезінде GC логтары тіркелді:
- Aikar G1GC (96G Heap): Ең ұзақ GC тоқтауы — 284.1 мс; Орташа тоқтау — 42.5 мс.
- Generational ZGC (96G Heap): Ең ұзақ GC тоқтауы — 0.84 мс; Орташа тоқтау — 0.64 мс.
Осылайша біз Minecraft серверлеріндегі ең басты ауру — мерзімді микрофриздерді толықтай жеңдік.