質問: javafx8を用いてあるプログラムを作ったのですが, 何もさせていないのに実行直後からタスクマネージャに表示されたjavaw.exeのメモリ使用量が増え続けます.(数十分後には約1GBまで) Eclipse memory Analyzerを用いてプログラムのヒープ領域を調べてみたのですが,ほとんど変化はありませんでした.(60MBほどで一定) Eclipseのデバックモードでスレッドの数も見てみましたが変化はありませんでした. このような状況下において考えられるメモリリークの原因を教えていただきたいです.
回答: http://www.atmarkit.co.jp/ait/articles/0505/26/news111.html しかし、Javaにおいても、メモリ・リークが完全になくなったわけではありません。 例えば、JavaオブジェクトAのオブジェクト変数fooが、JavaオブジェクトBを参照しているケースを考えます。 この場合、たとえBがプログラムの処理上は不要になったとしても、fooからBへの参照が存在する限り、 Bはガベージ・コレクションの対象とはなりません。 このように、プログラマが予想しないところでオブジェクトの参照が残ってしまうことを、 「メモリ・リテンション」と呼びます。特に、コレクションや配列を参照元とするメモリ・リテンションが多発すると、 解放されないJavaオブジェクトが継続的に増加し、メモリ・リーク状態に陥ります。 http://skrb.hatenablog.com/entry/20120302/p1 リソースのクローズ忘れによるメモリリークです。 たとえば、JDBC のコネクションやストリームのクローズを忘れていて、 いつのまにかリソースを食いつぶしていたというのはよくある話です。 いちおうファイナライザでクローズは呼ばれますが、 ファイナライザはコールされないこともあるので、ファイナライザに依存したコードは書くべきではないのです。 try-with-resoucrs を使えば、そういう問題を未然に防ぐことができるのだということが重要なんです。 http://blog.cybozu.io/entry/8218 次に、ヒープが正常だった理由にも納得です。 FileInputStream はファイルの中身をヒープに確保するようなことはせず、 native コードで読み出します。なのでヒープ上に現れないのですね。 finalize に 頼 っ て は い け な い