Forum: Ruby Failed to allocate memory while I use multi-threads

Posted by Edward QU (autogyro)
on 2012-12-31 03:42
Dear all
I got a error message while I was running a multi-threads program.

OS is WINDOWS 2003,
Ram is 4G.
ruby:1.92 p290

the program is:

scheduler = Rufus::Scheduler.start_new
check_process_job = scheduler.every '30m' do |job|

threads = ThreadGroup.new
thread= [check_process_queue] unless
check_process_queue.respond_to?(:each)
    check_process_queue.each{ |line|
    threads.add Thread.new(line){ |l|
    unless check_process_queue.size<1
          do ........

the number of line is less than 500.

any help would be great appreciated!

Regards
Qu
Posted by Robert Klemme (robert_k78)
on 2012-12-31 12:27
(Received via mailing list)
On Mon, Dec 31, 2012 at 3:43 AM, Edward QU <lists@ruby-forum.com> wrote:

> I got a error message while I was running a multi-threads program.

> the number of line is less than 500.

I can make a program crash for memory reasons in far less lines.

$ time ruby -e 'a=["*"];loop {a << (a.last + "*")}'
-e:1:in `block in <main>': failed to allocate memory (NoMemoryError)
        from -e:1:in `loop'
        from -e:1:in `<main>'

real    0m50.809s
user    0m3.041s
sys     0m4.695s

> any help would be great appreciated!

Difficult without seeing the whole program and knowing all the
libraries you use.  You could insert regular dumps of class statistics
via ObjectSpace in order to get an idea of most allocated objects,
e.g.

stat=Hash.new 0
ObjectSpace.each_object {|o| stat[o.class]+=1}

A bit more involved:

# LIB -------------

require 'monitor'

$stat = Hash.new(0).extend MonitorMixin

def $stat.count(o)
  synchronize do
    self[caller(4)] += 1
  end

  o
end

def $stat.dump(n = 10)
  synchronize do
    sort_by {|s,c| c}.last(n).each do |s, c|
      printf "%10d %s\n", c, s[0..5].join('|')
    end
  end
end

def replace_new(cl)
  cl.class_eval do
    alias _new new

    def new(*a,&b)
      $stat.count(_new(*a,&b))
    end
  end

  cl
end

replace_new Class

class <<Struct
  alias _new new

  def new(*a, &b)
    _new(*a, &b).tap do |cl|
      replace_new(cl.singleton_class)
    end
  end
end

# TEST -------------

S = Struct.new :x

class Y
  def initialize(x) @x=x end
end

5.times {|i| S.new i
  Y.new i+1 }

$stat.dump


Cheers

robert
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.