rubyjs / therubyracer

Embed the V8 Javascript Interpreter into Ruby
1.66k stars 192 forks source link

memory usage, memory leaks(?) #311

Closed niv closed 10 years ago

niv commented 10 years ago

Hi,

I'm seeing some pretty high memory usage when eval()ing stuff inside a V8 context. Granted, the given usecase may be a bit extreme for most cases, but it would affect long-running processes pretty drastically I'd have to imagine.

Very simple example code:

$ irb -rtherubyracer  # on ruby 2.1.2
# Make a few contexts
ctx = []; 1000.times do ctx << V8::Context.new end
# => about 135MB of RSS used
# eval some stuff in all contexts
100.times do ctx.each do |c| c.eval("var a = 1;"); end; end; nil
# => 155MB of rss. Again.
100.times do ctx.each do |c| c.eval("var a = 1;"); end; end; nil
# => 166. Again.
100.times do ctx.each do |c| c.eval("var a = 1;"); end; end; nil
# => 177 MB ..

You get the picture. I'd assume that a simple eval would not allocate resources and then not free them again. Running the garbage collector will not improve matters.

Is this the intended behaviour? Why is it behaving this way?

cowboyd commented 10 years ago

The problem is that the V8 garbage collector is not running because you haven't trigger any of its threshholds. I believe it's around 1G before it will start collecting garbage.

try calling V8::C::IdleNotification()

niv commented 10 years ago

You're right! Silly me. Thanks.

cowboyd commented 10 years ago

You can also set the the memory usage limits in the V8 vm with the ResourceConstraints class which is undocumented. If I go over this with you, would you be interested in writing a guide for it in the wiki?