メッセージ。 - ちょっと調べました
# ちょっと調べました
だいたいわかってきました。
ファイナライザがついてるオブジェクト、およびそこからたどれるオブジェクトは、一度ごみと判断されてもファイナライザを走らせるためにGCサイクル一回分、延命されます。
一方GCは、あるサイクルで回収したメモリが少なかった場合、メモリ領域を拡張します。
ということは、あるサイクルでごみになったオブジェクトのほとんどがファイナライザつきオブジェクト、およびそこからたどれるオブジェクトの場合、意味的にそれらはごみであるにもかかわらず、GCはメモリ領域の拡張を要求することになります。
今回のサンプルコードのように、ループ内でファイナライザリーチャブルなオブジェクトのみをがんがんアロケートしている場合、そのようなケースが多発し、そのたびに使用メモリが増えて行くことになります。
言ってみれば、回収はされてるんだけど間に合ってない、という感じですかね。
上のパッチでメモリが増えなくなるのは、ファイナライザつきオブジェクトからのリーチャビリティを明示的に切ることで、即時回収率が上がっているからだと思われます。
要らなくなったポインタを積極的にNULLにしてやるようにすれば防げそうです。
ファイナライザがついてるオブジェクト、およびそこからたどれるオブジェクトは、一度ごみと判断されてもファイナライザを走らせるためにGCサイクル一回分、延命されます。
一方GCは、あるサイクルで回収したメモリが少なかった場合、メモリ領域を拡張します。
ということは、あるサイクルでごみになったオブジェクトのほとんどがファイナライザつきオブジェクト、およびそこからたどれるオブジェクトの場合、意味的にそれらはごみであるにもかかわらず、GCはメモリ領域の拡張を要求することになります。
今回のサンプルコードのように、ループ内でファイナライザリーチャブルなオブジェクトのみをがんがんアロケートしている場合、そのようなケースが多発し、そのたびに使用メモリが増えて行くことになります。
言ってみれば、回収はされてるんだけど間に合ってない、という感じですかね。
上のパッチでメモリが増えなくなるのは、ファイナライザつきオブジェクトからのリーチャビリティを明示的に切ることで、即時回収率が上がっているからだと思われます。
要らなくなったポインタを積極的にNULLにしてやるようにすれば防げそうです。
Comment
Trackback