Feature #2328

malloc_limit の肥大化を防ぎたい

Added by _ wanabe over 5 years ago. Updated about 4 years ago.

Status:Rejected
Priority:Normal
Assignee:-

Description

=begin
何らかの原因で malloc_limit が肥大化してしまうと、GC のタイミングが遅れて
Bug #1325 のように異常なほどのスワップや NoMemoryError を引き起こしかねません。
改善案としてパッチを二つ書きました。よろしければご検討ください。
また、このパッチが問題になるケースがあれば教えていただけるとありがたいです。

  1. vm_xrealloc() での malloc_increase のチェックおよび増加量の抑制

vm_xrealloc() では、malloc_increase は上限チェック無しで増加しており、
これは上記の問題につながります。
単純に vm_xmalloc() と同様の上限チェックを行うと GC が起こりすぎるので、
malloc_increase の増加量を、それまでの増加量の平均値(よりやや小さい値)だけ
抑制することで、メモリ使用量の近似値を取り、GC 回数を減らしました。

  1. GC ごとの malloc_limit の直接的な減少

  2. の対策をとっても、例えば malloc_increase が上限に近いときに大きなサイズの
    malloc がされることが続いた場合、malloc_limit は減少することなく増加し続けます。
    膨大なメモリを使う場合やプロセスの寿命が長い場合は特に蓄積量が大きいと思われます。
    この対策として、GC のたびに malloc_limit を何割かずつ減らすのはどうでしょうか。
    パッチでは 1/16 ほどの値を減らしています。
    =end

suppress_malloc_increase-1.patch Magnifier (1.88 KB) _ wanabe, 11/04/2009 08:28 AM

suppress_malloc_increase-2.patch Magnifier (604 Bytes) _ wanabe, 11/04/2009 08:28 AM

test.rb Magnifier (559 Bytes) _ wanabe, 11/04/2009 09:01 PM

log.txt Magnifier (1.51 KB) _ wanabe, 11/04/2009 09:01 PM

History

#1 Updated by Yukihiro Matsumoto over 5 years ago

=begin
まつもと ゆきひろです

In message "Re: [Feature #2328] malloc_limit の肥大化を防ぎたい"
on Wed, 4 Nov 2009 08:28:12 +0900, _ wanabe redmine@ruby-lang.org writes:

|何らかの原因で malloc_limit が肥大化してしまうと、GC のタイミングが遅れて
|Bug #1325 のように異常なほどのスワップや NoMemoryError を引き起こしかねません。
|改善案としてパッチを二つ書きました。よろしければご検討ください。
|また、このパッチが問題になるケースがあれば教えていただけるとありがたいです。

私は思いつきません。ベンチマーク(こんなケースでこんなに改善
とか、こんなケースでは悪くならないとか)があると採用しやすい
と思います。

=end

#2 Updated by _ wanabe over 5 years ago

=begin

私は思いつきません。ベンチマーク(こんなケースでこんなに改善
とか、こんなケースでは悪くならないとか)があると採用しやすい
と思います。

ありがとうございます。改善される例とその実行結果を添付しました。
悪くならないケースはそれらしいものが思いつきませんでした。すみません。

malloc/realloc の後に、1MB の文字列を 2000 個生成しています。
リネームの都合上 miniruby ですが、恐らく ruby でもあまり変わらないと思います。
-v は、いずれも ruby 1.9.2dev (2009-11-02 trunk 25630) [i386-mingw32] です。

まとめると、以下のような結果になりました。
メモリの潤沢な環境では、数値をいじらないと差が出ないかもしれません。

通常の miniruby, 大量 realloc 後: 277 秒(GC: 12 回)
パッチ 1 適用時, 大量 realloc 後: 10 秒(GC: 286 回)
パッチ 2 適用時, 大量 realloc 後: 285 秒(GC: 13 回)
両パッチ 適用時, 大量 realloc 後: 10 秒(GC: 286 回)

通常の miniruby, 大量 malloc 後: 141 秒(GC: 30 回)
パッチ 1 適用時, 大量 malloc 後: 155 秒(GC: 30 回)
パッチ 2 適用時, 大量 malloc 後: 27 秒(GC: 66 回)
両パッチ 適用時, 大量 malloc 後: 29 秒(GC: 66 回)

なお手元では、両パッチ適用後 make test-all が 3722 秒 から2435 秒になりました。
(ブロックしてしまうので test_io.rb の test_dup_many はスキップしていますが)
=end

#3 Updated by Yukihiro Matsumoto over 5 years ago

=begin
まつもと ゆきひろです

In message "Re: [Feature #2328] malloc_limit の肥大化を防ぎたい"
on Wed, 4 Nov 2009 21:01:41 +0900, _ wanabe redmine@ruby-lang.org writes:

|> 私は思いつきません。ベンチマーク(こんなケースでこんなに改善
|> とか、こんなケースでは悪くならないとか)があると採用しやすい
|> と思います。
|
|ありがとうございます。改善される例とその実行結果を添付しました。
|悪くならないケースはそれらしいものが思いつきませんでした。すみません。

<略>

ありがとうございます。とても説得力のあるベンチマークだと思い
ました。人工的なテストだけでなく、test-allも性能が改善してい
る点が好印象です。

コミットしていただけませんか?

=end

#4 Updated by _ wanabe over 5 years ago

=begin
すみません、そのあと遠藤さんに追試をしていただいたのですが(ありがとうございます)
人工的なテストの結果は再現せず、また make test-all ではむしろ 434 秒 -> 469 秒と
悪化してしまったそうです。
3 回ずつのテストで誤差は±3秒ほどだったそうなので信頼できる値だと思います。

なので、環境依存で結果が大きく変わるものであることは間違いないようです。
かえって遅くなる場合があるというのは大問題だと思いますので
大変申しわけないのですが Reject 扱いにしていただけないでしょうか。
=end

#5 Updated by _ wanabe over 5 years ago

  • Status changed from Open to Rejected

=begin

=end

Also available in: Atom PDF