操作
バグ #479
完了バグ #474: コードベース健全性: メモリリーク・重大バグの一括調査と修正
並行処理レース・無制限キャッシュの是正
バグ #479:
並行処理レース・無制限キャッシュの是正
説明
現象¶
複数スレッドが同期なしで共有可変状態にアクセスし、可視性不足・レース・CME・スレッド未終了の温床がある。再現条件が状況依存なため、実装着手時に各項を再検証する。
対象箇所¶
-
AbstractAudioDriver 並列ロード
src/bms/player/beatoraja/audio/AbstractAudioDriver.java:410-
BoundedParallelExecutor(:440)の並列ロードでlocalSlice[note.getWav()]への check-then-create レース + 非スレッドセーフな libgdxArray.add。タスクキー(wavid)とスライス処理キー(note.getWav())が別 ID になり得るため同一要素を複数スレッドが触る。スライス音源欠落/AIOOBE の温床。
-
-
AbstractResult/MusicResult の非 volatile 共有
src/bms/player/beatoraja/result/AbstractResult.java:20,35,39/MusicResult.java- IR 送信ワーカースレッド(
startVirtual("beatoraja-ir-music-result", ...))が非 volatile なstate/ranking/rankingOffsetを書き、描画スレッドが同期なしで読む。IR 結果が描画に反映されない/古い state のまま遷移等。
- IR 送信ワーカースレッド(
-
PortAudioDriver
src/bms/player/beatoraja/audio/PortAudioDriver.java:29,193,246-249- ミキサー停止フラグ
stopが非 volatile(スレッド未終了でスレッド+オーディオストリームリークの恐れ)。:249は最大 1 秒の CPU スピンウェイト。
- ミキサー停止フラグ
-
BitmapFontCache
src/bms/player/beatoraja/skin/BitmapFontCache.java:11- static
HashMapが無制限増加・エビクションなし、かつスキン読込スレッドと描画スレッドから並行アクセスで CME/破損リスク。
- static
参考:StreamController の busy-wait src/bms/player/beatoraja/stream/StreamController.java:70
¶
-
while (!pipeBuffer.ready());で CPU 1 コアをスピン消費(資源浪費、機能バグではない)。
修正方針¶
-
stop/stateの volatile 化。localSliceへの並列アクセスを同期 or per-key ロック化。BitmapFontCacheをConcurrentHashMap+ 上限/解放に。rankingの差し替え/更新はロック。スピンウェイトは適切な待機に置換。 - 影響範囲が広いため、必要に応じて個別チケットに分割して慎重に対応。
検証¶
- 並列ロードを繰り返してもスライス音源欠落/AIOOBE が出ない。
- IR 結果がリザルトに反映される。
- 終了時にオーディオスレッドが確実に停止する。
操作