[#47033] [ruby-trunk - Bug #8749][Open] Readline.readline stops STDOUT? — "no6v (Nobuhiro IMAI)" <nov@...>
9 messages
2013/08/07
[#47036] Re: [ruby-trunk - Bug #8749][Open] Readline.readline stops STDOUT?
— Tanaka Akira <akr@...>
2013/08/07
2013/8/7 no6v (Nobuhiro IMAI) <nov@yo.rim.or.jp>:
[#47564] [ruby-trunk - Bug #8719][Open] r42096 make bm_app_factorial.rb slow — "authorNari (Narihiro Nakamura)" <authorNari@...>
4 messages
2013/08/02
[#47565] [ruby-trunk - Bug #8719] r42096 make bm_app_factorial.rb slow
— "authorNari (Narihiro Nakamura)" <authorNari@...>
2013/08/02
[#47569] [ruby-trunk - Feature #8726][Open] Class#source_location — "takiuchi (Genki Takiuchi)" <genki@...21g.com>
14 messages
2013/08/03
[#47574] Re: [ruby-trunk - Feature #8726][Open] Class#source_location
— KOSAKI Motohiro <kosaki.motohiro@...>
2013/08/03
> Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。
[#47575] Re: [ruby-trunk - Feature #8726][Open] Class#source_location
— KOSAKI Motohiro <kosaki.motohiro@...>
2013/08/03
> なるせさん、わたし、あのバックトレースの整形処理がイマイチ理解できんのだが、
[#47609] Re: [ruby-cvs:49669] naruse:r42527 (trunk): refix r42525 set stdio_file only if stdio — Tanaka Akira <akr@...>
2013/8/12 <naruse@ruby-lang.org>:
7 messages
2013/08/12
[#47610] Re: [ruby-cvs:49669] naruse:r42527 (trunk): refix r42525 set stdio_file only if stdio
— "NARUSE, Yui" <naruse@...>
2013/08/12
あぁ、[ruby-dev:47608]見てませんでした。
[#47611] Re: [ruby-cvs:49669] naruse:r42527 (trunk): refix r42525 set stdio_file only if stdio
— Tanaka Akira <akr@...>
2013/08/12
2013年8月12日 11:38 NARUSE, Yui <naruse@airemix.jp>:
[#47614] Re: [ruby-cvs:49669] naruse:r42527 (trunk): refix r42525 set stdio_file only if stdio
— "NARUSE, Yui" <naruse@...>
2013/08/12
editline の問題は、editlineにはrl_getcがなく、かつreadline.cで、
[#47620] Ruby 2.1 開発者会議 2013-08-31 のお知らせ — "NARUSE, Yui" <naruse@...>
かなり暑いですが、こんにちは。
5 messages
2013/08/14
[#47649] Re: [ruby-changes:30564] akr:r42643 (trunk): * process.c (rb_proc_times): Use RB_GC_GUARD to guard objects from GC. — SASADA Koichi <ko1@...>
akr さん
4 messages
2013/08/21
[#47650] Re: [ruby-changes:30564] akr:r42643 (trunk): * process.c (rb_proc_times): Use RB_GC_GUARD to guard objects from GC.
— Tanaka Akira <akr@...>
2013/08/21
2013/8/21 SASADA Koichi <ko1@atdot.net>:
[#47663] Re: [ruby-core:56878] [ruby-trunk - misc #8835][Open] Introducing a semantic versioning scheme and branching policy — "Akinori MUSHA" <knu@...>
At Fri, 30 Aug 2013 21:49:34 +0900,
6 messages
2013/08/30
[#47664] Re: [ruby-core:56878] [ruby-trunk - misc #8835][Open] Introducing a semantic versioning scheme and branching policy
— KOSAKI Motohiro <kosaki.motohiro@...>
2013/08/30
MjAxMy84LzMwIEFraW5vcmkgTVVTSEEgPGtudUBpZGFlbW9ucy5vcmc+Og0KPiBBdCBGcmksIDMw
[ruby-dev:47638] Re: [ruby-trunk - Bug #8711] 最近NoMemoryErrorが多い
From:
SASADA Koichi <ko1@...>
Date:
2013-08-19 05:37:56 UTC
List:
ruby-dev #47638
(2013/08/01 20:18), naruse (Yui NARUSE) wrote:
> http://u32.rubyci.org/~chkbuild/ruby-trunk/log/20130801T103302Z.log.html.gz
> で 32bit でも安定したような気がします。
>
> もうしばらく様子を見ます。
>
> より多くのアドレス空間を必要とするようになった事自体は仕様って理解でいいんですよね>ささださん
こちら、だいたいわかったんじゃないかなぁ、と思うので調査結果を報告します
(日本語)。小崎さん、チェックしてくれると助かります。
簡単な報告:
TestFiber#test_many_fibers が沢山仮想メモリを確保し、それを(なぜか)解
放しないため、その後の fork が ENOMEM で失敗します。
詳細な報告:
前提:
64bit OS で、2GB の物理メモリ+500MB の swap を持つシステム(VM)で検証
しています。Linux のバージョンは 3.2.0-51-generic。virtualbox 上で実行し
ています。
(1) TestFiber#test_many_fibers が仮想メモリを沢山確保してしまう
今は、Fiber のスタックは mmap で確保しています。Fiber が GC されると
munmap で解放するはずなんですが、何かの拍子にプロセスのアドレス空間が広
がったままになっているようです。これについては要検証。単に Fiber が GC
されない、というか、GC されたけど、実際の解放は遅延している、という気が
します。
Linux 側の RSS を見ると、1GB 弱しか使っていないことがわかりますが、仮想
メモリは 4GB ほど確保していることが観測できました。
Ruby 2.0 から、Fiber のためのスタックサイズが広がったため、この問題が生
じました(多分)。
(2) fork が ENOMEM で失敗
物理メモリ(+swap)以上の仮想メモリを持つプロセスを fork しようとする
と、ENOMEM が起って失敗するようです。
(3) ENOMEM になってしまう理由
Linux は、(デフォルトでは)一度に物理メモリ(+α)以上の mmap は出来な
いようになっているようです。
http://passingloop.tumblr.com/post/11957331420/overcommit-and-oom-killer
> 0
> オーバーコミット有効
> 一回の malloc で確保できるのは実際に利用可能なメモリの大きさまで
多分、この制限で fork() が失敗してるんじゃないかなぁ、と思います。ちなみ
に、このページの malloc って、mmap かなぁ。
Linux kernel のソースをおおざっぱに追ったのですが、fork() がこのチェック
をするところにどう到達するかは見ることが出来ませんでした。ので、推測にな
ります。
考えられる解決策:
- TestFiber#test_many_fibers を削除
- TestFiber#test_many_fibers を別プロセスで実行
- TestFiber#test_many_fibers 後にちゃんと物理メモリを解放するように頑張る
余談:
fork では、CoW になるから、ページテーブル操作だけ必要で、物理メモリの制
限はないだろー(fork 出来るだろう)、と思っていたんですが、そうでもない
んですね。
しかし、この Linux の制限って少し不思議ですね。mmap(4GB) を行うと、(3)
の条件で失敗しますが、mmap(2GB) を 2 回やると成功します。これだけだと連
続領域 4GB の確保が出来ないのかな、とも思いますが、実は MAP_WRITE を外す
と mmap(4GB) は成功します。どうやら、書き込み可能な部分だけ、この(3) の
チェックが入るようです。で、mprotect() で 2GB 単位でこの 4GB の連続領域
を書き込み可能にすることが可能です。つまり、
size = 4GB;
addr = mmap(0, size, PROT_EXEC | PROT_READ, ...);
mprotect(addr , size/2, 書き込み可能に);
mprotect(addr+size/2, size/2, 書き込み可能に);
とすると、書き込み可能な 4GB の連続領域を得ることが出来ます。もちろん、
実際に書き込んでいくとページが割り当てられてメモリ足りなくなりますが。
こういう設計なのは、なにがしかの理由があるんでしょうけれども、意外でした。
--
// SASADA Koichi at atdot dot net