이번 시간에는 지난 강의에 이어 Java의 GC 작업의 개념을 이해하고, 이를 최적화하는 방법에 대하여 알아볼 것이다.

마찬가지로 지난 강의를 모두 읽은 것을 전제로 작성하였으니, 아직 읽지 않았을 경우 여기를 눌러 차례대로 읽고 오면 도움이 될 것이다.


Java의 GC 작업이란?

마인크래프트 Java Edition이 사용하는 Java에는 GC(Garbage Collection)이라는 개념이 존재한다. 개발자들이 코드를 작성하다 보면 더 이상 쓰이지 않는 값이 생길 때가 많은데, C와 같은 다른 언어에서는 free() 또는 delete와 같은 함수 혹은 매소드를 사용하여 개발자가 직접 불필요한 값을 삭제해주어야 한다. 하지만 Java에서는 개발자가 직접 함수를 호출하여 값을 삭제할 필요 없이, 주기적으로 가비지 컬렉터가 작동하여 쓰이지 않는 값을 삭제해준다.

이러한 가비지 컬렉터에는 여러 종류가 있는데, 마인크래프트에서 기본값으로 사용되는 가비지 컬렉터는 비효율적인 편이다. 이를 해결하기 위해 Aikar라는 저명도 높은 개발자가 여러 시행착오 끝에 G1GC를 사용하는 보다 효율적인 가비지 컬렉터 설정을 공개하였다.

java -Xms10G -Xmx10G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar paperclip.jar nogui

출처: Tuning the JVM – G1GC Garbage Collector Flags for Minecraft, https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

1.15 이상의 마인크래프트 서버를 구축했다면 단순히 위 명령어를 사용하여 서버를 구동함으로써 가비지 컬렉션 작업을 최적화할 수 있다. 다만 6GiB 미만의 메모리를 사용하는 경우 이 명령어를 사용하는 것을 권장하지 않으며, 12GiB 이상의 메모리를 사용하는 경우 다음 명령어를 대신 사용하는 것이 좋다.

java -Xms12G -Xmx12G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar paperclip.jar nogui

출처: Tuning the JVM – G1GC Garbage Collector Flags for Minecraft, https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

메모리 할당량 변경이나 서버 소프트웨어 파일 경로 지정 등은 이 강의에서는 생략하도록 하겠다.

각종 콘피그 파일 최적화

기본적으로 Spigot, Paper에 적용된 설정은 성능에 초점을 둔 것이 아닌, 기본 Minecraft와 최대한 동일한 기전으로 동작하도록 설정되어 있다. 달리 말하자면, 콘피그 파일을 조금만 손보더라도 눈에 띄는 성능 개선을 일구어낼 수 있다.

YouHaveTroubleminecraft-optimization Github 레포지토리에는 이러한 콘피그 최적화 방법이 상세히 기술되어 있다. 해당 레포지토리의 README.md를 참고하여 자신의 서버에 맞게 콘피그를 조정하길 바란다. 특히 일부 설정은 적용한 이후 예기치 못한 문제가 발생할수도 있으니 (가령 맵을 프리로드하지 않은 상태에서 prevent-moving-into-unloaded-chunkstrue로 바꿀 경우 플레이어가 로드되지 않은 청크로 이동할 수 없게 된다) 적용 전 반드시 설명을 읽고 검토해보길 바란다.


마치며

오늘 준비한 강의는 여기서 끝이 난다. 다음 강의에서는 서버에서 지연(렉)을 유발하는 원인을 분석하고 이를 완화하는 방법과 각종 서버 취약점들에 대한 정보를 다룰 예정이다.


1강: 버전에 따른 최적화 정도 비교, 하드웨어 선택하기
2강: 서버 소프트웨어 선택, 맵 프리로드의 중요성
3강: GC 작업 최적화, 각종 Config 최적화
4강: 지연(렉) 분석, 서버 취약점의 개념과 방지 방법