プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

Java の closeDescriptors() このエントリーをはてなブックマークに追加

kzk さんに教えてもらったネタ

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6336770

Javaは新しいプロセス作るときに、ファイルディスクリプタを全部閉じようとするけども、実装がバグっているのでデッドロックが起きる可能性があるそうだ。

てきとうに見つけたクロスリファレンスサイトから引用すると
http://www.jiema.org/xref/openjdk/jdk7/jdk/src/solaris/native/java/lang/UNIXProcess_md.c#293

fork-and-exec処理の時のディスクリプタ全クローズ処理で、よりにもよってopendir()。ここでmalloc()が発生。あぼーん。

なんで、UNIX系OSってcloseall()システムコールがないんだろうね。困ったもんだ


追記: Linux限定の話でいうと /proc/{pid}/statusのFDSizeフィールドがmax fdを表しているので、3からFDSizeまでcloseしていけば、OKなんじゃないかという気がしてきた。誰か検証プリーズ

追記2: ついでにRubyの実装をちらりと見たけど、NOFILEまでしかクローズしていないから最大ファイルディスクリプタが動的なシステムだとリークしているっぽい。今度、akrさんあたりに真相を聞いてみよう。

追記3: glibc malloc はpthread_atfork()を使って、fork前後でmutexを取っているので、forkとexecの間でmalloc()呼んでも平気。これはtcmallocのような外部mallocを使った場合のみに問題になりそう

追記4: いくつかのページで sysconf(_SC_OPEN_MAX)を薦めているところがあったけど、これ、Linuxではうまくいかない。getrlimit()で現在のlimitを取っているだけなので、ファイルを開いた後で最大値を下げられたら、ちゃんとハンドリングできない。まあ、普通の人はそんな事しない。という指摘は正しいと思います

追記5: forkとexecの間はasync signal safeしかダメって話は以前にも書いたので、そっちも見てね
http://mkosaki.blog46.fc2.com/blog-entry-886.html

追記6: kzkさんに指摘されて気づいたけど、これが記念すべき1000エントリ目かー。妙に感慨深いな

追記7: kzkさんの関連エントリも参照のこと。
http://kzk9.net/blog/2009/09/deadlock_on_process_builder.html
関連記事


プログラミング | 【2009-09-14(Mon) 22:29:58】 | Trackback:(0) | Comments:(5)
コメント

closefrom とか。

http://stackoverflow.com/questions/899038/getting-the-highest-allocated-file-descriptor

Ruby がてきとうなのはその通りです。
それなりには動くので、まぁ、そのうち困ったら。
(そうなったときに fdwalk が普及しているといいなぁ)
2009-09-14 月 10:44:29 | URL | akr #- [ 編集]

fdwalkはclosefrom以外に使い道があんまり思いつかないのですが、有用ですかね?たぶんclosefrom()だと、1つだけ閉じたくないfdがあるのだが、それがたまたま大きな番号って時に困るのだけれども、実運用で起きるのはどういう時だろう。
そもそも、追記1で書いた方法でmaxfd 取ってきて、closeしまくる作戦でもNOFILEよりかはマシになりそう。どうせ、通常のケースではmaxfdってせいぜい1024ぐらいな気がするし。
2009-09-14 月 22:16:40 | URL | kosaki #- [ 編集]

できれば FD_CLOEXEC をつけるだけにしておきたいので。

なんでかというと、valgrind 上で動かした時とか、使用中の fd があったりするのです。

FDSize: で maxfd を得る方法は悪くはないと思います。プラットフォーム限定であることを除けば。
2009-09-15 火 05:09:35 | URL | akr #- [ 編集]

え?え?
ついていけなかった。execする直前だと、FD_CLOEXEC しても close()しても結果は同じになりませんか?
うーむ、何か見落としている気がする
2009-09-15 火 06:46:08 | URL | kosaki #- [ 編集]

Ruby から見ると exec 直前でも、valgrind から見ると直前ではないようで。
隠蔽が甘いというべきかもしれませんが。
2009-09-15 火 10:27:30 | URL | akr #- [ 編集]
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。