プロジェクト

全般

プロフィール

バグ #478

完了

バグ #474: コードベース健全性: メモリリーク・重大バグの一括調査と修正

音源/ファイル書き出しのハンドルリーク解消(FLAC/MP3/Course)

バグ #478: 音源/ファイル書き出しのハンドルリーク解消(FLAC/MP3/Course)

エージェント ちゃん さんが7日前に追加. 6日前に更新.

ステータス:
完了
優先度:
通常
担当者:
対象バージョン:
開始日:
2026/06/29
期日:
進捗率:

100%

予定工数:

説明

現象

Closeable が try-with-resources 外または例外パスで close されず、OS ファイルハンドルがリークする。FLAC 主体の譜面集で「Too many open files」や Windows でのファイルロック残留に直結。

対象箇所

  1. FLAC(確定・最優先) src/bms/player/beatoraja/audio/PCM.java:289
    • FLACDecoder input = new FLACDecoder(new BufferedInputStream(Files.newInputStream(p))); がメソッド内で一度も close されない。FLAC キー音を読むたびハンドルリーク。
  2. MP3 src/bms/player/beatoraja/audio/PCM.java:256
    • bitstream.close() が正常系末尾(:280)のみ。デコード中例外 → catch(Throwable){}(:284)握りつぶしでハンドルリーク。
  3. 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日前に更新 操作 #1

  • ステータス未着手 から 実装中 に変更
  • 進捗率0 から 10 に変更

実装に着手しました。

  • ブランチ: feature/478
  • 対応方針: FLAC/MP3 デコード(PCM.java)と Course 保存(CourseDataAccessor.java)の Closeable を try-with-resources 化してファイルハンドルリークを解消し、空 catch を Logger 記録に置き換える

エージェント ちゃん さんが6日前に更新 操作 #2

  • ステータス実装中 から 完了 に変更
  • 進捗率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 の BitstreamAutoCloseable 非実装を確認)。デコード中例外を握りつぶしていた空 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.javasrc/bms/player/beatoraja/CourseDataAccessor.javasrc/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。必要に応じて別チケットで対応

他の形式にエクスポート: PDF Atom