Hard question: Any ideas why this code leaks memory?

S

Sven C. Koehler

Hello,

could someone help me understand why this code leaks memory? (I am using
ruby 1.8.6 (2007-12-03 patchlevel 113) [x86_64-linux].)

def rss_leaks
/^VmRSS:\s+(\d+)/m.match(File.open("/proc/#{$$}/status") {|f|
f.read })[1].to_i
end

| irb(main):002:0> 100000.times { rss_leaks }; rss_leaks
| => 11624
| irb(main):003:0> 100000.times { rss_leaks }; rss_leaks
| => 16836
| irb(main):004:0> 100000.times { rss_leaks }; rss_leaks
| => 22008
| irb(main):005:0> 100000.times { rss_leaks }; rss_leaks
| => 27248
| irb(main):006:0> 100000.times { rss_leaks }; rss_leaks
| => 32468

Calling GC.start inbetween does not help, but when we rewrote rss_leaks
this way the leaks disappeared:

def rss_no_leaks()
d = File.open("/proc/#{$$}/status") {|f| f.read }
/^VmRSS:\s+(\d+)/m.match(d)[1].to_i
end

| irb(main):002:0> 100000.times { rss_no_leaks }; rss_no_leaks
| => 6568
| irb(main):003:0> 100000.times { rss_no_leaks }; rss_no_leaks
| => 6568
| irb(main):004:0> 100000.times { rss_no_leaks }; rss_no_leaks
| => 6588
| irb(main):005:0> 100000.times { rss_no_leaks }; rss_no_leaks
| => 6592
| irb(main):006:0> 100000.times { rss_no_leaks }; rss_no_leaks
| => 6572

Any help to further understand what actually causes these leaks would be
very appreaciated!

Best wishes,

Sven
 
X

Xavier Noria

def rss_leaks
/^VmRSS:\s+(\d+)/m.match(File.open("/proc/#{$$}/status") {|f|
f.read })[1].to_i
end

No idea about the leak, just wanted to point out for the archives that
/m does nothing there because there's no dot.

/m in Ruby is /s in Perl ("." matches "\n"), and Perl's /m (multi-line
mode) is always on in Ruby, there's no way to switch that one off. ^
is always beginning of line, and you assert beginning of string with
\A. To tangle this a little more /s in Ruby exists and means the
regexp is written in the SJIS encoding.
 
N

Nobuyoshi Nakada

Hi,

At Wed, 20 Aug 2008 04:46:24 +0900,
Sven C. Koehler wrote in [ruby-talk:311847]:
could someone help me understand why this code leaks memory? (I am using
ruby 1.8.6 (2007-12-03 patchlevel 113) [x86_64-linux].)

def rss_leaks
/^VmRSS:\s+(\d+)/m.match(File.open("/proc/#{$$}/status") {|f|
f.read })[1].to_i
end
Calling GC.start inbetween does not help, but when we rewrote rss_leaks
this way the leaks disappeared:

def rss_no_leaks()
d = File.open("/proc/#{$$}/status") {|f| f.read }
/^VmRSS:\s+(\d+)/m.match(d)[1].to_i
end

Seems a bug.
 
S

Sven C. Koehler

At Wed, 20 Aug 2008 12:49:41 +0900,
Sven C. Koehler wrote in [ruby-talk:311908]:

Hmmm, indeed. But it seems to occur with the latest 1.8.

I tried some of the patches mentioned on the page on my ruby-1.8.6, and this is
the patch which worked for me (saves me some time before upgrading to 1.8.7).

-S.

--- parse.old.y 2008-08-20 10:59:56.000000000 +0000
+++ parse.y 2008-08-20 11:08:16.000000000 +0000
@@ -5716,7 +5716,7 @@
rb_mem_clear(vars+i, len-i);
}
else {
- *vars++ = (VALUE)ruby_scope;
+ *vars++ = 0;
rb_mem_clear(vars, len);
}
ruby_scope->local_vars = vars;
@@ -5732,6 +5732,7 @@
if (!(ruby_scope->flags & SCOPE_CLONE))
xfree(ruby_scope->local_tbl);
}
+ ruby_scope->local_vars[-1] = 0; /* no reference needed */
ruby_scope->local_tbl = local_tbl();
}
}
 
N

Nobuyoshi Nakada

Hi,

At Wed, 20 Aug 2008 20:19:43 +0900,
Sven C. Koehler wrote in [ruby-talk:311956]:
I tried some of the patches mentioned on the page on my ruby-1.8.6, and this is
the patch which worked for me (saves me some time before upgrading to 1.8.7).

It has been applied to the latest 1.8, of course.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top