操作
バグ #478
完了バグ #474: コードベース健全性: メモリリーク・重大バグの一括調査と修正
音源/ファイル書き出しのハンドルリーク解消(FLAC/MP3/Course)
バグ #478:
音源/ファイル書き出しのハンドルリーク解消(FLAC/MP3/Course)
説明
現象¶
Closeable が try-with-resources 外または例外パスで close されず、OS ファイルハンドルがリークする。FLAC 主体の譜面集で「Too many open files」や Windows でのファイルロック残留に直結。
対象箇所¶
-
FLAC(確定・最優先)
src/bms/player/beatoraja/audio/PCM.java:289-
FLACDecoder input = new FLACDecoder(new BufferedInputStream(Files.newInputStream(p)));がメソッド内で一度も close されない。FLAC キー音を読むたびハンドルリーク。
-
-
MP3
src/bms/player/beatoraja/audio/PCM.java:256-
bitstream.close()が正常系末尾(:280)のみ。デコード中例外 →catch(Throwable){}(:284)握りつぶしでハンドルリーク。
-
-
CourseDataAccessor
src/bms/player/beatoraja/CourseDataAccessor.java:83-
OutputStreamWriterが try-with-resources 外。write()/flush()例外でclose()未到達 → Windows でファイルロック残留。
-
修正方針¶
-
FLACDecoder/Bitstream/OutputStreamWriterを try-with-resources 化。 - 空 catch をやめ Logger 記録(#472 の慣習に従い
Logger.getGlobal().log(Level.WARNING, msg, e))。OGG パス(PCM.java:251 の空 catch)もログ記録を検討。
検証¶
- FLAC 多用譜面の連続プレイでファイルハンドル数(lsof 相当)が頭打ちになる。
- コース保存時に書き込み例外が出てもファイルロックが残らない。
エージェント ちゃん さんが6日前に更新
- ステータス を 未着手 から 実装中 に変更
- 進捗率 を 0 から 10 に変更
実装に着手しました。
- ブランチ:
feature/478 - 対応方針: FLAC/MP3 デコード(
PCM.java)と Course 保存(CourseDataAccessor.java)のCloseableを try-with-resources 化してファイルハンドルリークを解消し、空 catch をLogger記録に置き換える
エージェント ちゃん さんが6日前に更新
- ステータス を 実装中 から 完了 に変更
- 進捗率 を 10 から 100 に変更
対応が完了しました。
概要¶
FLAC/MP3 デコード(PCM.java)と Course 保存(CourseDataAccessor.java)で、Closeable が例外パスや try-with-resources 外で close されず OS ファイルハンドルがリークしていた問題を解消した。
変更点¶
-
FLAC (
PCM.java): 基底BufferedInputStreamを try-with-resources 化。FLACDecoderに close API は無いが、基底ストリームを閉じてハンドルを確実に解放。 -
MP3 (
PCM.java): 基底BufferedInputStreamを try-with-resources 化(JLayer のBitstreamはAutoCloseable非実装を確認)。デコード中例外を握りつぶしていた空 catch を WARNING ログ記録に変更。 -
OGG (
PCM.java): 握りつぶしていた空 catch を WARNING ログ記録に変更。 -
CourseDataAccessor.write:
FileOutputStream/BufferedOutputStream/OutputStreamWriterを try-with-resources 化し、write/flush例外時もファイルロックを残さない。文字コード指定をStandardCharsets.UTF_8に変更。 - 変更ファイル:
src/bms/player/beatoraja/audio/PCM.java、src/bms/player/beatoraja/CourseDataAccessor.java、src/test/java/bms/player/beatoraja/CourseDataAccessorWriteTest.java(新規)の 3 件
テスト¶
-
.\gradlew.bat test: 成功(全スイート) - 新規
CourseDataAccessorWriteTest: write→read/readAll ラウンドトリップ、削除→再書き込み(ハンドルリーク無し確認)の 2 ケース
関連 MR¶
- !153 (feature/478 → develop)
残課題(本チケットスコープ外)¶
- 同一ファイル内の類似リーク:
PCM.javaの WAV 内蔵 MP3 デコードパス、CourseDataAccessor.read()の JSON 読込 InputStream。必要に応じて別チケットで対応
操作