Project

General

Profile

Bug #11332

Arrayの操作でcrubyインタプリタのメモリリークが起きる

Added by metanest (Makoto Kishimoto) almost 4 years ago. Updated almost 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-dev:49166]

Description

きしもとです

Arraysort! と、pop または shift の操作を組み合わせると、わずか
ですが ruby インタプリタのメモリリークを引き起こすようです。多数回
繰返すと、どんどん大きくなります。

以下のサンプルを手元の環境(FreeBSD/amd64のruby 2.1.6、ruby 2.2.2、
trunk (r51120) )で試すと、どれもインタプリタのプロセスのメモリ
サイズが大きくなっていきます(最後はメモリを確保できなくなって
落ちる)。
# ObjectSpace.memsize_of_all で調べるとオブジェクトは増えたり
# 大きくなったりはしていません。

# -*- mode:ruby ; coding:utf-8 -*-

def sample rg
    arr = []
    sz = 5 + rg.rand(5)
    i = 0
    while i < sz do
        arr[i] = rg.rand
        i += 1
    end
    until arr.empty? do
        arr.sort!

        arr.pop
        #arr.shift
    end
end

randgen = Random.new 12345
count = 0
while true do
    sample randgen
    if (count += 1) > 1000000 then
        count = 0
        p "GC"
        GC.start
    end
end

Related issues

Has duplicate Ruby trunk - Bug #11333: Arrayの操作でcrubyインタプリタのメモリリークが起きるClosedActions
Has duplicate Ruby trunk - Bug #11334: Arrayの操作でcrubyインタプリタのメモリリークが起きるClosedActions

Associated revisions

Revision 48129219
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51147 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 51147
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

Revision 51147
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

Revision 51147
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

Revision 51147
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

Revision 51147
Added by nobu (Nobuyoshi Nakada) almost 4 years ago

array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

History

#1

Updated by wanabe (_ wanabe) almost 4 years ago

  • Has duplicate Bug #11333: Arrayの操作でcrubyインタプリタのメモリリークが起きる added
#2

Updated by wanabe (_ wanabe) almost 4 years ago

  • Has duplicate Bug #11334: Arrayの操作でcrubyインタプリタのメモリリークが起きる added

Updated by wanabe (_ wanabe) almost 4 years ago

ruby -e 'loop { [1, 2, 3, 4].tap(&:pop).sort! }' とすると、同じ現象と思われるメモリ増加が確認できました。
(ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14])

loop { [1, 2, 3, 4, 5].tap(&:pop).sort! } でも loop { [1, 2, 3].tap(&:pop).sort! } でもメモリ増加は見られなかったので、
RARRAY_EMBED_FLAGrb_ary_modify() などが関係あるのかもしれない、という気がします。

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

Array#popだけで起きるような気がします。

$ for i in 1 5 10 100 1000 10000; do echo; echo $i; ruby2.2 -r ./test/lib/memory_status.rb -e "puts m0 = Memory::Status.new; 10000.times{[*1..$i].pop}; GC.start; puts m1 = Memory::Status.new; p m1.rss.fdiv(m0.rss)"; done

1
{size:2536062976,rss:7557120}
{size:2536062976,rss:7577600}
1.002710027100271

5
{size:2516140032,rss:7319552}
{size:2517188608,rss:8900608}
1.2160044767767209

10
{size:2519285760,rss:7335936}
{size:2520334336,rss:9162752}
1.2490228922389726

100
{size:2526625792,rss:7458816}
{size:2559131648,rss:22032384}
2.9538714991762767

1000
{size:2518237184,rss:7528448}
{size:2612609024,rss:90443776}
12.013601741022851

10000
{size:2517188608,rss:7331840}
{size:2636726272,rss:140148736}
19.115083798882683

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

  • Description updated (diff)

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

popだけで起きるのはOSXのlibc固有のようでした。
Linuxではたしかに4要素から3要素に減らしたあとでsort!した場合だけのようです。

#7

Updated by nobu (Nobuyoshi Nakada) almost 4 years ago

  • Status changed from Open to Closed

Applied in changeset r51147.


array.c: fix memory leak

  • array.c (rb_ary_sort_bang): the original array may not be embedded even if a substitution array is embedded, as it is embedded when the original array is short enough but not embedded. [ruby-dev:49166] [Bug #11332]

Updated by metanest (Makoto Kishimoto) almost 4 years ago

rev.51148 で実行して直っていることを確認しました

Also available in: Atom PDF