【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

アバター
SugarCoffee
ID: 1YA1R2HPEM
記事: 148
登録日時: 2019年10月19日(土) 14:21
いいね: 8回
いいねされた回数: 3回

【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

投稿記事 by SugarCoffee » 2020年7月17日(金) 19:47

超がつくほどのレアケースだと思いますが、もし他の人で同一な現象が発生するケースもありうるので書き留めます。

発生対象
  • 起動引数から大きなメモリ量を割り当てている -Xmx24G 等
  • 多くのMODを導入している
  • F3のデバッグ情報画面で割り当てられた膨大なメモリを消費している

症状
マインクラフトをプレイ中、突如fpsが低下(1~5fps)、しばらくの間(1、2分ほど)ゲームがフリーズする。
その後解消するが、すぐにfpsの低下を繰り返す。

原因
GC(ガーベジコレクション)の動作
リソースリーク

GC(ガーベジコレクション)とは、Javaに搭載されている自動でメモリを掃除してくれる仕組みのようなものです。
ですが使用メモリ量が大きければ大きいほど、リフレッシュ(掃除開始)時のラグが大きくなります。
そのため後述のリソースリークと合わさり、異常なラグが生じていたと考えられます。

リソースリークとは何らかの要因によってGCがメモリの一部を掃除できなくなった状態を指します

今回発生したラグでは使用メモリが95%~100%を繰り返しており、ほとんどが開放できない状態(掃除しても95%にするのが限界)になった。
もしくは普通にメモリを使い切ってしまいGCが常時フル稼働する状態になり、異常なラグが発生したと推測しました。

対処方法
  • 導入modの数を減らす
  • 二分探索を行い競合が起きるmodの組み合わせを特定する
  • 総当りで競合が起きるmodの組み合わせを特定する
  • メモリ割り当て量を更に増やし、物理的にリソースリークに対抗する(オススメできません)
等が考えられます。
 
私の場合は、特定ディメンションでのみ発生し、modが多すぎてmodを追加すると、即ArrayIndexOutOfBoundsExceptionが発生する状態にあったので、そもそもそのディメンションに立ち寄らないということで解決しました。
 
GCやリソースリークに詳しいわけではないので、ツッコミどころがあれば是非お願いします。

このトピックに関係しない質問などは書き込まないでください
ゲーム中のラグ報告、質問などは適切なカテゴリ、トピックにお願いします
0



アバター
こなとーふ
ID: 5ZR3DN3LSS
記事: 13
登録日時: 2020年6月09日(火) 21:09
連絡する:

Re: 【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

投稿記事 by こなとーふ » 2020年7月18日(土) 11:26

いくつか対処方法で挙げられるものに提案と補足です。

ガベージコレクション(以下GC)のチューニングを行うのも一つの手かと思いますが、あくまでもマイクラ標準では膨大なMODを処理することを想定して設定されているわけではないと思うので、JVM引数でGC方式を見直すのも良いかと思います。

仰る通り、膨大なメモリを割り当てた後の、GC処理にはアプリケーション停止時間はどうしても膨大な時間が掛かってしまいますが、それを考慮して最大一時停止時間目標(-XX:MaxGCPauseMillis)が設定されているものの、上手くメモリ開放ができなければ、断続的な一時停止が発生してしまいます。

標準では-XX:MaxGCPauseMillis50msですが、結構体感ではっきりとわかってしまうほどです。
といえど、これを単純に増減させればいいかというとそうでもなく、増やせばそれだけ一時停止を許容してしまうことになるので、さらにラグがひどくなったりもするかと思います。

チューニングにはこの辺を見直す必要があると思いますが、個々のマシンスペックによって最適値は異なるので、一概にこれといったことは言えません。

マイクラ標準設定のJVMでは、GC方式をG1 GC方式(-XX:+UseG1GC)を採用していますが、Concurrent方式(-XX:+UseConcMarkSweepGC)に変更するのも良いかと思います。

但し、Concurrent方式はアプリケーションスレッドと並列でGC処理を行う為、かなりのパフォーマンスヒットが考えられるので、それ相応のマシンスペックが必要(割り当てメモリ量が多ければ、さらに必要)で、以下設定が自動割り当てとなってしまうのに注意が必要です。

コード: 全て選択

-XX:SurvivorRatio=1024
-XX:MaxTenuringThreshold=0
アプリケーションスレッドと並列でGC処理を行うので、正しく処理が行えていればさらに停止時間は短縮化できますが、パフォーマンスヒットによってマシン側が処理しきれない場合は、もっと悪化する可能性はあります。
その場合は、Concurrent方式をインクリメンタルモード(-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode)で動作させれば、改善されるかもしれません。
但し、これも完全に有能というわけではなく、マシンスペック次第では非常に断続的なラグを発生させる要因にもなるので、チューニングしながら最適設定を探すしかないのかもしれません。

あくまでも一つ提案かつ、動作テストしていないはご愛嬌…
私の認識が間違っていたらご指摘ください。
0
マインクラフトやその他いろんなことの技術的情報が大好物。
何でも自動化しないと気が済まない人です。

サーバ・ネットワーク関係
トラブルシュート関係
ZenScript
Modding

について投稿してます。

Twitter : https://twitter.com/konatofu_game/
画像

アバター
SugarCoffee
ID: 17FOJKHF86
記事: 148
登録日時: 2019年10月19日(土) 14:21
いいね: 8回
いいねされた回数: 3回

Re: 【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

投稿記事 by SugarCoffee » 2020年7月19日(日) 12:30

こなとーふ さんが書きました: 2020年7月18日(土) 11:26 いくつか対処方法で挙げられるものに提案と補足です。

ガベージコレクション(以下GC)のチューニングを行うのも一つの手かと思いますが、あくまでもマイクラ標準では膨大なMODを処理することを想定して設定されているわけではないと思うので、JVM引数でGC方式を見直すのも良いかと思います。

...
提案と補足ありがとうございます。起動引数からGCを-XX:+UseConcMarkSweepGCに変更したところ異常なラグが消滅し劇的な改善が見られました。GC方式によってここまで差が出るとは…

こなとーふ さんありがとうございました。大変、勉強になりました。
また、-XX:+UseG1GCでは、使用中メモリが多くなる->GCが走る->使用中メモリが最低限になる
を繰り返しており、全く気が付きませんでしたが、-XX:+UseConcMarkSweepGCでは、メモリ使用量が右肩上がりの、数十分では影響が出ないとても緩やかな1次関数になっておりそのディメンションでのみ、何かしらのリソースリーク(メモリリーク)が増大し続けているようであることも分かりました。

ヒープダンプからリソースリーク元を特定する手法もあるようなので、何かしら追加で分かればこのトピックに追記しようと思います。
もしくはリソースリーク元の特定として別のディスカッショントピックにするかもしれません。
0

アバター
かーふーん
ID: 5W8WGKJXNB
記事: 11
登録日時: 2020年5月04日(月) 22:45
Minecraft ID: carphooon
いいね: 11回
いいねされた回数: 5回
連絡する:

Re: 【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

投稿記事 by かーふーん » 2020年7月20日(月) 01:18

GC方式について一つ補足を呟いておきます

今回のケースのようにヒープ領域が巨大な場合、新方式のGCであるShenandoah GCを使用するという選択肢もあります
100GBと2GBの停止時間が変わらないそうです
ただしRed HatのOpenJDK8でしか使えません

コード: 全て選択

-XX:+UseShenandoahGC
0

ゆっくり実況を出しています
画像
Twitter: @carphooon
Discord: carphooon226#4378

アバター
SugarCoffee
ID: 5IVXU5AVCP
記事: 148
登録日時: 2019年10月19日(土) 14:21
いいね: 8回
いいねされた回数: 3回

Re: 【質問禁止】膨大なメモリ[24GB等]を割り当てている場合に発生する異常なラグ

投稿記事 by SugarCoffee » 2020年8月05日(水) 21:06

かーふーん さんが書きました: 2020年7月20日(月) 01:18 GC方式について一つ補足を呟いておきます

...
補足、ありがとうございました。
Red HatOpenJDKのライセンス形態をあまりわかっていないので、今は利用自体がなかなか難しいですね…。Java12ではRedHat以外でも試験的に有効化することもできるようになっているそうなので、MODありのMinecraftをJava12以降で実行できる頃には活用できそうです。
0

返信する