java.nio.channels.FileChannelのクローズ漏れによる非ページプール(Pool nonpaged bytes)リークでメモリ枯渇

はじめに

開発中のJavaアプリケーションをWindowsで数日間稼働させたら、マシンのメモリをすべて食い尽くすという事象に遭遇しました。

その際の調査録です。

環境情報

  • Java8のアプリケーション
  • Windows10(Windows2008R2でも同事象を確認)

発生した事象

  • マシンのメモリの使用率が100%
  • 非ページプール(Pool nonpaged bytes)が大部分を占める
  • 開発中のJavaアプリを停止すると空きメモリが大量にできる

という状況だったにも関わらず

  • Javaアプリのヒープダンプ(jmap)上は特にリークしているオブジェクトがない
  • タスクマネージャでプロセス毎のメモリを見ても、Javaアプリはメモリをそんなに使ってない(xmx程度)
  • タスクマネージャでプロセス毎の非ページプール使用量を見てもJavaアプリは全然使ってない

Javaアプリ停止でメモリが開放されるので、Javaアプリが原因でメモリリークしているのは間違いないはずなのに。。。

先に結論

ファイルハンドル(java.nio.channels.FileChannel)のクローズ漏れがあり、クローズが漏れたファイルハンドルが累積していったことが原因でした。

ファイルハンドルのクローズ漏れは非ページプール(Pool nonpaged bytes)のリークにも繋がるんですね。(開発中のアプリケーションは10分おきに2000ファイルを開く定期タスクがありハンドルをリークさせていきました)

この状況の場合、タスクマネージャで見た時にJavaアプリのメモリ使用量は増えませんが、非ページプールはファイルハンドルリーク数に比例して増えていってるのでぱっと見メモリリークに気づくことができません。

調査に使用したツール

調査で参考にした情報

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA