From: takeru sasaki Date: 2009-09-11T01:34:01+09:00 Subject: [ruby-dev:39302] Re: [Bug #2067] bodyが大きいエラーページをopen-uriで取得するとfdがリークしている 言いだしっぺの佐々木です。 begin open(url) do |f| ... end rescue OpenURI::HTTPError => e e.io.close end GC.start の様に書けば確実にcloseされるのなら問題ないですが、そうでもないようです。 GCでは未使用のメモリを回収してくれるだけで未使用のfdを回収してくれることは ないのですよね。 メモリに余裕がある状態だとfdをつかんだ例外オブジェクトも回収されず、 fdも開きっぱなしになるのではないかとおもいます。 (再現スクリプトでは1.9では開きっぱなしのfdの数が少ないです。GCが効いている?) この問題に気がついたのは、「EMFILE too many open files」になったせいでした。 例外オブジェクトへの参照は確実に無いはずで(メソッドからreturnしている) gcされるより前にtoo many open filesにぶつかったのでした。 大きいサイズのエラーページというのもレアなのでなかなか気づきにくい問題でした。 2009年9月10日22:56 Tanaka Akira : > In article , > Yukihiro Matsumoto writes: > >> 部分的にしか理解できていません。Tempfileなのでcloseすると情報 >> が失われるから保存しているのは理解できました。が、その場合、 >> 気になるのは、今回「リーク」とされたのは、ただちにcloseされて >> いないからプロセスが肥大しただけのことで、いずれGCで回収され >> るのかどうか、ということです。 > > 例外オブジェクトへの参照がなくなれば、その例外オブジェクトや > Tempfile は GC されます。GC にともない、fd は close され、テ > ンポラリファイルは削除されます。 > >> Tempfileは面倒だなあ。 > > [ruby-core:25019] で書いた Tempfile.anonymous {} のような、 > 状況によっては面倒でない挙動をとれる API をつければいくらか > は軽減できるでしょう。ただし、今回の open-uri の場合は例外の > 中に入れるので適用できませんが。 > -- > [田中 哲][たなか あきら][Tanaka Akira] > >