Hard question: Any ideas why this code leaks memory?

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

On Tue, Aug 19, 2008 at 9:46 PM, Sven C. Koehler [email protected]
wrote:

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.

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.

On Wed, Aug 20, 2008 at 11:50:16AM +0900, Nobuyoshi N. wrote:

Seems a bug.

Yep, and it seems to be fixed in 1.8.7-p71 :
http://rubyforge.org/tracker/?func=detail&aid=15425&group_id=426&atid=1698

-S.

Hi,

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

Yep, and it seems to be fixed in 1.8.7-p71 :
http://rubyforge.org/tracker/?func=detail&aid=15425&group_id=426&atid=1698

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

On Wed, Aug 20, 2008 at 03:44:15PM +0900, Nobuyoshi N. wrote:

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

Yep, and it seems to be fixed in 1.8.7-p71 :
http://rubyforge.org/tracker/?func=detail&aid=15425&group_id=426&atid=1698

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();
      }
    
    }

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.

Issue #461 has been updated by Roger P…

You should try SVN HEAD and see if it’s still there.
See also
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=15425&group_id=426

http://redmine.ruby-lang.org/issues/show/461

Issue #461 has been updated by Shyouhei U…

Category set to core
Status changed from Assigned to Feedback

Can this still happen? I can’t observe on my machine with
ruby 1.8.8dev (2010-09-24 revision 27061) [x86_64-linux].

irb(main):005:0> 100000.times { rss_leaks }; rss_leaks
=> 5616
irb(main):006:0> 100000.times { rss_leaks }; rss_leaks
=> 5616
irb(main):007:0> 100000.times { rss_leaks }; rss_leaks
=> 5616
irb(main):008:0> 100000.times { rss_leaks }; rss_leaks
=> 5616


http://redmine.ruby-lang.org/issues/show/461