So you want to make Ruby leak memory? Here's a simple way....

K

khaines

Make a hash:

h = {'a' => 1, 'b' => 2, 'c' => 3}

And make another out of it:

Hash[h]

Do that a lot. Watch RAM vanish. GC cleans up the objects out of object
space just fine, but RAM trickles away nonetheless.

Here is a test program:

loop do
attrs = Hash['this','that','the other','enough','stuff','for six']
Hash[attrs]
end

I have tested it on an installation of RedHat Enterprise Linux with 1.8.1,
1.8.2, 1.8.4, and 1.8.5 and also under 1.8.4 (one click installer) on
WinXP Home.

I've ran it under valgrind and just straight, and have inserted code to
run GC after each loop iteration. The behavior is consistent. If you
eliminate the Hash[attrs] line, there is no leak.


Kirk Haines
 
K

Kent Sibilev

Interesting. Does this patch fixes it?

Index: hash.c
===================================================================
RCS file: /src/ruby/hash.c,v
retrieving revision 1.128.2.16
diff -u -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 00:14:17 -0000
@@ -328,6 +328,7 @@
hash = hash_alloc(klass);

RHASH(hash)->ifnone = Qnil;
+ st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);

return hash;


Make a hash:

h = {'a' => 1, 'b' => 2, 'c' => 3}

And make another out of it:

Hash[h]

Do that a lot. Watch RAM vanish. GC cleans up the objects out of object
space just fine, but RAM trickles away nonetheless.

Here is a test program:

loop do
attrs = Hash['this','that','the other','enough','stuff','for six']
Hash[attrs]
end

I have tested it on an installation of RedHat Enterprise Linux with 1.8.1,
1.8.2, 1.8.4, and 1.8.5 and also under 1.8.4 (one click installer) on
WinXP Home.

I've ran it under valgrind and just straight, and have inserted code to
run GC after each loop iteration. The behavior is consistent. If you
eliminate the Hash[attrs] line, there is no leak.


Kirk Haines
 
K

khaines

Interesting. Does this patch fixes it?

Index: hash.c
===================================================================
RCS file: /src/ruby/hash.c,v
retrieving revision 1.128.2.16
diff -u -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 00:14:17 -0000
@@ -328,6 +328,7 @@
hash = hash_alloc(klass);

RHASH(hash)->ifnone = Qnil;
+ st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);

return hash;

It does indeed. Yay.


Kirk Haines
 
F

Francis Cianfrocca

Interesting. Does this patch fixes it?

Index: hash.c
===================================================================
RCS file: /src/ruby/hash.c,v
retrieving revision 1.128.2.16
diff -u -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 00:14:17 -0000
@@ -328,6 +328,7 @@
hash = hash_alloc(klass);

RHASH(hash)->ifnone = Qnil;
+ st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);

return hash;


Bravo, Kent. Props.
 
R

Rob Sanheim

Make a hash:

h = {'a' => 1, 'b' => 2, 'c' => 3}

And make another out of it:

Hash[h]

Do that a lot. Watch RAM vanish. GC cleans up the objects out of object
space just fine, but RAM trickles away nonetheless.

Here is a test program:

loop do
attrs = Hash['this','that','the other','enough','stuff','for six']
Hash[attrs]
end

I have tested it on an installation of RedHat Enterprise Linux with 1.8.1,
1.8.2, 1.8.4, and 1.8.5 and also under 1.8.4 (one click installer) on
WinXP Home.

I've ran it under valgrind and just straight, and have inserted code to
run GC after each loop iteration. The behavior is consistent. If you
eliminate the Hash[attrs] line, there is no leak.


Kirk Haines

Wow...that seems to be a pretty major leak to have made it this long
w/o being noticed. Maybe that type of behavior isn't repeated often
enough in most programs to expose the leak?

- rob
 
K

khaines

Wow...that seems to be a pretty major leak to have made it this long
w/o being noticed. Maybe that type of behavior isn't repeated often
enough in most programs to expose the leak?

It's a small enough leak that it takes a lot of iterations to start to add
up. And while the threshold of pain involved in chasing that thing down
wasn't horrible, it's high enough that I can understand people doing what
I have done for a long time:

Oh, that process is getting a bit big.
*kill* *restart*

Or they assume that it's a bug in their code somewhere and do the same
thing.

Look at the discussion about Mutex leaking last week.

BTW, my test code makes use of a number of mutexes and heavy use of
threading, and after running 120k hits through it, the RAM usage is rock
solid at 13.8Mb. Normally after that many hits it would have grown to
around 45mb. So, this is very pleasing to me.


Kirk Haines
 
J

Just Another Victim of the Ambient Morality

Interesting. Does this patch fixes it?

Index: hash.c
===================================================================
RCS file: /src/ruby/hash.c,v
retrieving revision 1.128.2.16
diff -u -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 00:14:17 -0000
@@ -328,6 +328,7 @@
hash = hash_alloc(klass);

RHASH(hash)->ifnone = Qnil;
+ st_free_table(RHASH(hash)->tbl);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);

return hash;

It does indeed. Yay.

Nice!
 
N

nobu

Hi,

At Tue, 29 Aug 2006 09:15:27 +0900,
Kent Sibilev wrote in [ruby-talk:211236]:
Interesting. Does this patch fixes it?

Yes, and modified it slightly.


Index: hash.c
===================================================================
RCS file: /cvs/ruby/src/ruby/hash.c,v
retrieving revision 1.128.2.16
diff -p -U 2 -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 03:43:58 -0000
@@ -224,7 +224,8 @@ rb_hash_foreach(hash, func, farg)
}

+static VALUE hash_alloc0 _((VALUE));
static VALUE hash_alloc _((VALUE));
static VALUE
-hash_alloc(klass)
+hash_alloc0(klass)
VALUE klass;
{
@@ -233,9 +234,19 @@ hash_alloc(klass)

hash->ifnone = Qnil;
- hash->tbl = st_init_table(&objhash);

return (VALUE)hash;
}

+static VALUE
+hash_alloc(klass)
+ VALUE klass;
+{
+ VALUE hash = hash_alloc0(klass);
+
+ RHASH(hash)->tbl = st_init_table(&objhash);
+
+ return hash;
+}
+
VALUE
rb_hash_new()
@@ -326,7 +337,5 @@ rb_hash_s_create(argc, argv, klass)

if (argc == 1 && TYPE(argv[0]) == T_HASH) {
- hash = hash_alloc(klass);
-
- RHASH(hash)->ifnone = Qnil;
+ hash = hash_alloc0(klass);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);
 
K

Kent Sibilev

Sure thing. The table initialization in this case is redundant.

Hi,

At Tue, 29 Aug 2006 09:15:27 +0900,
Kent Sibilev wrote in [ruby-talk:211236]:
Interesting. Does this patch fixes it?

Yes, and modified it slightly.


Index: hash.c
===================================================================
RCS file: /cvs/ruby/src/ruby/hash.c,v

retrieving revision 1.128.2.16
diff -p -U 2 -r1.128.2.16 hash.c
--- hash.c 6 Jul 2006 15:44:26 -0000 1.128.2.16
+++ hash.c 29 Aug 2006 03:43:58 -0000
@@ -224,7 +224,8 @@ rb_hash_foreach(hash, func, farg)
}

+static VALUE hash_alloc0 _((VALUE));
static VALUE hash_alloc _((VALUE));
static VALUE
-hash_alloc(klass)
+hash_alloc0(klass)
VALUE klass;
{
@@ -233,9 +234,19 @@ hash_alloc(klass)

hash->ifnone = Qnil;
- hash->tbl = st_init_table(&objhash);

return (VALUE)hash;
}

+static VALUE
+hash_alloc(klass)
+ VALUE klass;
+{
+ VALUE hash = hash_alloc0(klass);
+
+ RHASH(hash)->tbl = st_init_table(&objhash);
+
+ return hash;
+}
+
VALUE
rb_hash_new()
@@ -326,7 +337,5 @@ rb_hash_s_create(argc, argv, klass)

if (argc == 1 && TYPE(argv[0]) == T_HASH) {
- hash = hash_alloc(klass);
-
- RHASH(hash)->ifnone = Qnil;
+ hash = hash_alloc0(klass);
RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl);
 
S

Stefan Schmiedl

It's a small enough leak that it takes a lot of iterations to start to add
up.

.... but no memory leak is small enough to evade you forever, Kirk :)

Grrrrreat work!
s.

PS. Did you get my mail last week?
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: So you want to make Ruby leak memory? Here's a simple way...."
on Tue, 29 Aug 2006 12:46:51 +0900, (e-mail address removed) writes:

|At Tue, 29 Aug 2006 09:15:27 +0900,
|Kent Sibilev wrote in [ruby-talk:211236]:
|> Interesting. Does this patch fixes it?
|
|Yes, and modified it slightly.

OK, can you commit?

matz.
 

Members online

Forum statistics

Threads
473,744
Messages
2,569,481
Members
44,900
Latest member
Nell636132

Latest Threads

Top