AI使ってゲームの負荷改善してみる

ここ1年程GTNHで遊んでいて、常について回っていたサーバーの負荷。
最近はTPSでは問題ないけど、下記の警告メッセージが絶えず流れていて、ゲーム内での機械の処理時間も間延びしている。

[Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2034ms behind, skipping 40 tick(s)

きっかけは、AIとの壁打ち。
仕事の関係で、色々やっているうちに、「コレ、使えないかな」と思って自宅にてやってみた次第。

プロンプトを作るのは怠いので、とりあえず断片的に情報を入れていく。

CPUやメモリ、ディスク、GPUの環境
サーバーの構成
使っているJavaバージョン
サーバー起動コマンドライン
出力されているログ
遅延原因の事例を要求
Javaのコマンドライン改善を要求

で、まとめてプロンプトを出力してもらう。

以下プロンプトに従い対応してください

# 目的
Minecraftの超高難易度工業Modpack「GT: New Horizons (GTNH)」のマルチサーバーにおいて、頻発するサーバーの遅延警告(Can't keep up!)の原因を特定し、根本的に解消するための具体的な最適化アドバイスやトラブルシューティング手順を求めています。

# 前提環境
- ゲーム/Modpack: GT: New Horizons (GTNH) バージョン 2.8.4
- 実行環境: サーバーとクライアントを分けたマルチサーバー構成
- サーバーで使用しているJavaバージョン: Java 25.0.2
- クライアントで使用しいるJavaバージョン: Java 21.0.2
- サーバが動作するPCの性能 CPU:AMD Ryzen 5 5600G 実装RAM:32GByte GPU:NVIDIA GeForce 1060 3GB データ配置ドライブ:CT1000MX500SSD1
- ゲームの進行具合は、電圧世代がUHVに入っている。

# 発生している問題
- サーバーログに以下の警告(WARN)が継続的に出力され、サーバーがラグ(遅延)を起こしている。ログの内容は最後に記載する。
- 時には10秒以上の大幅な処理遅延(ティック・スキップ)が発生している。

# 今の設定
- 下記のコマンドラインで起動
 『java -Xms8G -Xmx8G -XX:+UseZGC -XX:+ZGenerational -XX:MaxGCPauseMillis=2 -XX:+UnlockDiagnosticVMOptions -XX:+UseStringDeduplication -Dfml.readTimeout=180 @java9args.txt -jar lwjgl3ify-forgePatches.jar nogui』

依頼事項
上記の前提条件とこれまでの流れを踏まえ、以下の点について最新の知見に基づいた専門的な回答を根拠と合わせて提示してください。
・GTNH 2.8.4サーバーのパフォーマンスを最大化するための「最適化された完全な起動引数(JVM引数)」の提案。

# 現在のサーバーログ
[14:16:00] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 4017ms behind, skipping 80 tick(s)
[14:16:30] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 18686ms behind, skipping 373 tick(s)
[14:16:32] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2593ms behind, skipping 51 tick(s)
[14:17:06] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 19873ms behind, skipping 397 tick(s)
[14:17:11] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 4713ms behind, skipping 94 tick(s)
[14:17:47] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 19896ms behind, skipping 397 tick(s)
[14:17:50] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 3631ms behind, skipping 72 tick(s)

何度かJavaのコマンドラインを差し替えて、起動しては結果を入力して、と、繰り返している内に遅延の長さが短くなってきた。平均しても半分以上は短くなっている。
ゲームにログインして確認してみたら、機械の処理時間の間延びも解消しているし、サクサク動く。
ただ、まだ警告は止まりはしていない。合間見てもう少し改善していきたい。

[10:55:46] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2119ms behind, skipping 42 tick(s)
[10:56:02] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2597ms behind, skipping 51 tick(s)
[10:58:40] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2870ms behind, skipping 57 tick(s)
[10:58:56] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2138ms behind, skipping 42 tick(s)
[10:59:12] [Server thread/WARN]: Can't keep up! Did the system time change, or is the server overloaded? Running 2341ms behind, skipping 46 tick(s)

快適に遊べる。いや、だいぶ久しぶりだ、この感覚。
Javaのオプションはわかりづらいので、ここをAIに丸投げして改善できたのは大きい。
あとはゲーム内の構造とか配置とかで負荷をかけなければ、当分は快適に遊べそうだ。

参考として、内の環境では最終的なコマンドラインは次のようになった。
オプションの意味もAI君に出してもらった。
まぁ意味については、ハルシネーションが混ざっているかもしれないので注意。

java -Xms12G -Xmx12G -XX:+UseZGC -XX:+ZGenerational -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders -XX:+UseStringDeduplication -XX:ZAllocationSpikeTolerance=5 -XX:ConcGCThreads=3 -XX:ParallelGCThreads=6 -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -Dfml.readTimeout=180 @java9args.txt -jar lwjgl3ify-forgePatches.jar nogui

1. メモリ割り当てに関するオプション
 • -Xms12G
  起動時の初期ヒープメモリサイズを 12GB に固定します。
 • -Xmx12G
  最大ヒープメモリサイズを 12GB に制限します。

2. ガベージコレクション(GC)に関するオプション
 • -XX:+UseZGC
  超低遅延ガベージコレクターである ZGC (Z Garbage Collector) を有効にします。
 • -XX:+ZGenerational
  世代別ZGC(Generational ZGC)を有効にするオプションです。
• ⚠️ 25.0.2での注意:Java 24以降、ZGCは「世代別モード」のみに一本化されたため、このオプションは不要(無視され警告が出る、または不要なフラグ)となっています。-XX:+UseZGC だけで自動的に世代別ZGCになります。
 • -XX:ZAllocationSpikeTolerance=5
  メモリ割り当ての急激な増加(スパイク)に対する、ZGCの「警戒度」を調整します。デフォルト(2)より高い 5 にすることで、メモリ不足に陥る前に余裕を持って前倒しでGCを開始させ、カクつきを防ぎます。
 • -XX:ConcGCThreads=3
  アプリケーションの実行と同時に(並行して)動くGCスレッド数を 3 に指定します。
 • -XX:ParallelGCThreads=6
  アプリを一時停止して処理する(STWなど極めて短い瞬間の)並列GCスレッド数を 6 に指定します。

3. Java 25 の最新最適化オプション
 • -XX:+UnlockExperimentalVMOptions
  実験的な機能(オプション)のロックを解除します。
 • -XX:+UseCompactObjectHeaders
  Java 25 で導入された非常に強力な最適化「コンパクトオブジェクトヘッダ」を有効にします。オブジェクトが持つシステム内部の管理データを半分(128bit ➔ 64bit)に削減することで、Modによる大量のアイテムやエンティティがあっても、ヒープメモリの大幅な節約(10〜20%減)とパフォーマンス向上が見込めます。
 • -XX:+UseStringDeduplication
  メモリ内にある重複した文字列(String)を自動的に1つに集約し、メモリを節約します。

4. システムプロパティ(-D オプション)
 • -Dsun.io.useCanonCaches=false
  Java内部のファイルパスの正規化キャッシュを無効にします。古いMod環境などで、ファイルの読み込みバグやメモリリークを防ぐために指定される定番の古いおまじないです。
 • -Djava.net.preferIPv4Stack=true
  ネットワーク通信において IPv4 を優先して使用します。IPv6環境の不具合によるマルチプレイの接続トラブルを防ぎます。
 • -Dfml.readTimeout=180
  FML (Forge Mod Loader) の通信タイムアウト時間を180秒(3分)に延長します。大量のModを導入していると、起動時やサーバー接続時のデータ同期に時間がかかって切断されることがあるため、それを防ぐMinecraft Forge固有の設定です。

5. 引数ファイルと実行対象
 • @java9args.txt
  java9args.txt という外部ファイル内に書かれた別の起動オプション(Java 9以降で必要になったモジュール解放設定 --add-opens など)をこの場所に読み込みます。
 • -jar lwjgl3ify-forgePatches.jar
  指定した JAR ファイル(ここでは Forge環境を近代化するModプログラム)を実行します。
 • nogui
  サーバー起動時に、グラフィカルなGUIウィンドウを表示せず、コマンドライン(コンソール)のみで軽量に起動させます。