[#38392] Enumerable#gather_each — Tanaka Akira <akr@...>

ときに、複数行をまとめて扱いたいことがあります。

47 messages 2009/05/09
[#38394] Re: Enumerable#gather_each — ujihisa <ujihisa@...> 2009/05/09

ujihisaと申します。

[#38400] Re: Enumerable#gather_each — Yukihiro Matsumoto <matz@...> 2009/05/09

まつもと ゆきひろです

[#38399] Re: Enumerable#gather_each — "Akinori MUSHA" <knu@...> 2009/05/09

At Sat, 9 May 2009 15:30:20 +0900,

[#38405] Re: Enumerable#gather_each — Tanaka Akira <akr@...> 2009/05/10

In article <86r5yy2nrg.knu@iDaemons.org>,

[#38417] Re: Enumerable#gather_each — "Akinori MUSHA" <knu@...> 2009/05/10

At Sun, 10 May 2009 10:08:47 +0900,

[#38524] [Bug #1503] -Kuをつけた時、/[#{s}]/n と Regexp.new("[#{s}]",nil,"n") で実行結果が異なる — sinnichi eguchi <redmine@...>

Bug #1503: -Kuをつけた時、/[#{s}]/n と Regexp.new("[#{s}]",nil,"n") で実行結果が異なる

8 messages 2009/05/22

[ruby-dev:38448] GCの問題

From: keiju@... (Keiju ISHITSUKA)
Date: 2009-05-14 09:17:12 UTC
List: ruby-dev #38448
けいじゅ@いしつかです.

添付のプログラムを実行すると. ほとんどのオブジェクト(文字列)がGCで回収
されないまま残ってしまいます.

これって, ruby側でもっと効率よくGCするようにするってことは不可能でしょ
うか?

ちなみに, コメントをはずすとゴミが回収されます.

いろんなパターンのスクリプトも添付します. Queueを使っていても同じ問題
が起こります. 1.9系だとほぼ確実に再現しますし, 1.8系だと再現する場合も
あるってかんじになっています.


--
  def foo(times)
    exp = []

    times.times do
      exp.push rand.to_s
    end
    exp.push nil
    exp
  end

  def bar(exp)
    while e = exp.shift
      e
    end
    p exp
  end

  exp = foo(1000000)
  bar(exp)
  #exp = foo(100)
  #bar(exp)

  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count
-- 


__
---------------------------------------------------->> 石塚 圭樹 <<---
---------------------------------->> e-mail: keiju@ishitsuka.com <<---

Attachments (1)

test-gc.rb (2.7 KB, text/x-ruby)
case ARGV[0]
when "0"

  require "thread"

  class Exp
    def initialize(out)
      @output = out
      @q = Queue.new

      start_export
    end

    def push(e)
      @q.push e
    end

    def start_export
      Thread.start do
	while e = @q.pop
	  @output.push e
	end
      end
    end
  end

  class Imp
    def initialize
      @q = Queue.new
    end

    def push(e)
      @q.push e
    end

    def pop
      e = @q.pop
      return e
    end
  end

  imp = Imp.new
  exp = Exp.new(imp)

  1000000.times do
    exp.push rand.to_s
  end
  exp.push "EOS"


  while (e = imp.pop) != "EOS"
    e
  end

  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count

when "1"

  require "thread"
  
  exp = Queue.new

  1000000.times do
    exp.push ""
  end
  exp.push "EOS"


  while (e = exp.pop) != "EOS"
    e
  end

  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count

when "2"

  require "thread"

  def foo
    exp = Queue.new

    1000000.times do
      exp.push ""
    end
    exp.push "EOS"


    while (e = exp.pop) != "EOS"
      e
    end
  end

  foo

  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count


when "3"

  def foo
    exp = []

    1000000.times do
      exp.push rand.to_s
    end
    exp.push "EOS"


    while (e = exp.shift) != "EOS"
      e
    end
    p exp
  end

  foo
 
  sleep 1
  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count

when "4"

  def foo
    exp = []

    1000000.times do
      exp.push rand.to_s
    end
    exp.push "EOS"
    exp
  end

  def bar(exp)
    while (e = exp.shift) != "EOS"
      e
    end
    p exp
  end

  exp = foo
  bar(exp)
#  exp = foo
#  bar(exp)

  sleep 1
  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count


when "5"

  def foo(times)
    exp = []

    times.times do
      exp.push rand.to_s
    end
    exp.push nil
    exp
  end

  def bar(exp)
    while e = exp.shift
      e
    end
    p exp
  end

  exp = foo(1000000)
  bar(exp)
  #exp = foo(100)
  #bar(exp)

  sleep 1
  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count


when "6"

  def foo(times)
    exp = []

    times.times do
      exp.push rand.to_s
    end
    exp.push "EOS"
    exp
  end

  def bar(exp)
    while (e = exp.shift) != "EOS"
      e
    end
    p exp
  end

  t1 = Thread.start {
    exp = foo(1000000)
    bar(exp)
    exp = foo(100)
    bar(exp)
  }
  t2 = Thread.start {
    exp = foo(1000000)
    bar(exp)
    exp = foo(100)
    bar(exp)
  }
#  exp = foo
#  bar(exp)

  t1.join
  t2.join

  GC.start
  count = 0
  ObjectSpace.each_object(String){|s| count += 1}
  puts count



end



  

  
  

In This Thread

Prev Next