Doubt about GC

Hello there!

I have this program:

- -------------------------------------------------------------------------
class Car
  attr_reader :number
  def initialize(n)
    @number=n
    puts "Creating car no. #{n}:#{object_id}"
  end
  def to_s
    "Car no. #{@number}"
  end
end

def makeCar(n)
  c = Car.new(n)
end

def listCars
  puts "\nListing cars:"
  ObjectSpace.each_object(Car) {|o| puts "#{o}:#{o.object_id}"}
  puts
end

c1 = makeCar(1)
makeCar(2)
makeCar(3)

listCars()
makeCar(4)
makeCar(5)

listCars();

puts "Firing gc."
GC.start
listCars();
- -------------------------------------------------------------------------

When I run, I get:

Creating car no. 1:-604870360
Creating car no. 2:-604870370
Creating car no. 3:-604870410

Listing cars:
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Creating car no. 4:-604870500
Creating car no. 5:-604870490

Listing cars:
Car no. 4:-604870500
Car no. 5:-604870490
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Firing gc.

Listing cars:
Car no. 4:-604870500
Car no. 1:-604870360

My doubt is why Car no. 4 is still there, after running gc. There is no
reference to it outside the function, right? So it should not have be
sweeped by GC?

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
http://beam.to/taq
Usuário GNU/Linux no. 224050

You script returns the expected result for me (only car 1). WinXP, Ruby 1.8.2.

I'm guessing garbage collection is happening asynchronously, and that
your listCars executed before car 4 was collected? Try sleep(2) in
between GC.start and listCars to see if that changes the result.

This is only a guess, and could be very wrong. I have not looked at
the Ruby source to verify how garbage collection works.

Jason

···

On 5/16/05, Eustaquio Rangel de Oliveira Jr. <eustaquiorangel@yahoo.com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello there!

I have this program:

- -------------------------------------------------------------------------
class Car
        attr_reader :number
        def initialize(n)
                @number=n
                puts "Creating car no. #{n}:#{object_id}"
        end
        def to_s
                "Car no. #{@number}"
        end
end

def makeCar(n)
        c = Car.new(n)
end

def listCars
        puts "\nListing cars:"
        ObjectSpace.each_object(Car) {|o| puts "#{o}:#{o.object_id}"}
        puts
end

c1 = makeCar(1)
makeCar(2)
makeCar(3)

listCars()
makeCar(4)
makeCar(5)

listCars();

puts "Firing gc."
GC.start
listCars();
- -------------------------------------------------------------------------

When I run, I get:

Creating car no. 1:-604870360
Creating car no. 2:-604870370
Creating car no. 3:-604870410

Listing cars:
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Creating car no. 4:-604870500
Creating car no. 5:-604870490

Listing cars:
Car no. 4:-604870500
Car no. 5:-604870490
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Firing gc.

Listing cars:
Car no. 4:-604870500
Car no. 1:-604870360

My doubt is why Car no. 4 is still there, after running gc. There is no
reference to it outside the function, right? So it should not have be
sweeped by GC?

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
The easiest way to create, record and stream live video - Beings
Usuário GNU/Linux no. 224050
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)

iD8DBQFCiO4mb6UiZnhJiLsRAmJ7AJ9M8a1CsY/ksAW1fThdmIpeLbB7gwCcCz5w
+sh/g0F1Vork+DKH/xRj+9M=
=Tm+7
-----END PGP SIGNATURE-----

When I run it, I get:

Creating car no. 1:20722128
Creating car no. 2:20722116
Creating car no. 3:20722068

Listing cars:
Car no. 3:20722068
Car no. 2:20722116
Car no. 1:20722128

Creating car no. 4:20721960
Creating car no. 5:20721972

Listing cars:
Car no. 4:20721960
Car no. 5:20721972
Car no. 3:20722068
Car no. 2:20722116
Car no. 1:20722128

Firing gc.

Listing cars:
Car no. 1:20722128

Kent.

···

On 5/16/05, Eustaquio Rangel de Oliveira Jr. <eustaquiorangel@yahoo.com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello there!

I have this program:

- -------------------------------------------------------------------------
class Car
        attr_reader :number
        def initialize(n)
                @number=n
                puts "Creating car no. #{n}:#{object_id}"
        end
        def to_s
                "Car no. #{@number}"
        end
end

def makeCar(n)
        c = Car.new(n)
end

def listCars
        puts "\nListing cars:"
        ObjectSpace.each_object(Car) {|o| puts "#{o}:#{o.object_id}"}
        puts
end

c1 = makeCar(1)
makeCar(2)
makeCar(3)

listCars()
makeCar(4)
makeCar(5)

listCars();

puts "Firing gc."
GC.start
listCars();
- -------------------------------------------------------------------------

When I run, I get:

Creating car no. 1:-604870360
Creating car no. 2:-604870370
Creating car no. 3:-604870410

Listing cars:
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Creating car no. 4:-604870500
Creating car no. 5:-604870490

Listing cars:
Car no. 4:-604870500
Car no. 5:-604870490
Car no. 3:-604870410
Car no. 2:-604870370
Car no. 1:-604870360

Firing gc.

Listing cars:
Car no. 4:-604870500
Car no. 1:-604870360

My doubt is why Car no. 4 is still there, after running gc. There is no
reference to it outside the function, right? So it should not have be
sweeped by GC?

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
The easiest way to create, record and stream live video - Beings
Usuário GNU/Linux no. 224050
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)

iD8DBQFCiO4mb6UiZnhJiLsRAmJ7AJ9M8a1CsY/ksAW1fThdmIpeLbB7gwCcCz5w
+sh/g0F1Vork+DKH/xRj+9M=
=Tm+7
-----END PGP SIGNATURE-----

Hello Eustaquio,

My doubt is why Car no. 4 is still there, after running gc. There is no
reference to it outside the function, right? So it should not have be
sweeped by GC?

Unlikely but the stack marking is conservative. Maybe there is
something on the stack that looks like a pointer to Car no.4. In this
event Car no.4 will not be deleted.

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

Hi.

You script returns the expected result for me (only car 1). WinXP, Ruby

1.8.2.

Weird! Here I'm running Slackware 10.1-current, Ruby 1.8.2.

I'm guessing garbage collection is happening asynchronously, and that
your listCars executed before car 4 was collected? Try sleep(2) in
between GC.start and listCars to see if that changes the result.

No change, even if I sleep more than 2 seconds, but if I make

GC.start
sleep(1)
GC.start

it works, only rest Car 1.

This is only a guess, and could be very wrong. I have not looked at
the Ruby source to verify how garbage collection works.

But it's a beggining and prove me that I'm not at least fully crazy ehehe.
There is something there.

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Hi Lothar!

Unlikely but the stack marking is conservative. Maybe there is
something on the stack that looks like a pointer to Car no.4. In this
event Car no.4 will not be deleted.

Kind of some "memory dirty" or something like that?

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com

Usuário GNU/Linux no. 224050

Eustaquio Rangel de Oliveira Jr., 16-05-2005 17:19:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Lothar!

> Unlikely but the stack marking is conservative. Maybe there is
> something on the stack that looks like a pointer to Car no.4. In this
> event Car no.4 will not be deleted.

Kind of some "memory dirty" or something like that?

I'm in such a different hardware and I got a result somehow different in ruby1.8 and ruby1.9.

I've HT enabled and running the code in both versions left cars 1, 4 and 5 after GC.
If I sleep a lot of time (I've tried uo to 10 sec), in ruby1.8 it still left the three cars and in ruby1.9 only cars 1 and 5.

$ ruby --version
ruby 1.8.2 (2005-04-11) [i386-linux]

$ruby Car.rb

Creating car no. 1:-604682514
Creating car no. 2:-604682524
Creating car no. 3:-604682564

Listing cars:
Car no. 3:-604682564
Car no. 2:-604682524
Car no. 1:-604682514

Creating car no. 4:-604682654
Creating car no. 5:-604682644

Listing cars:
Car no. 4:-604682654
Car no. 5:-604682644
Car no. 3:-604682564
Car no. 2:-604682524
Car no. 1:-604682514

Sleeping...
Firing gc.

Listing cars:
Car no. 5:-604682644
Car no. 1:-604682514

todos@tiago:~/caio/prog/ruby$ ruby1.8 Car.rb
Creating car no. 1:-604583790
Creating car no. 2:-604583800
Creating car no. 3:-604583840

Listing cars:
Car no. 3:-604583840
Car no. 2:-604583800
Car no. 1:-604583790

Creating car no. 4:-604583930
Creating car no. 5:-604583920

Listing cars:
Car no. 4:-604583930
Car no. 5:-604583920
Car no. 3:-604583840
Car no. 2:-604583800
Car no. 1:-604583790

Sleeping...
Firing gc.

Listing cars:
Car no. 4:-604583930
Car no. 5:-604583920
Car no. 1:-604583790

and
$ ruby1.9 --version
ruby 1.9.0 (2005-04-12) [i386-linux]

$ruby1.9 Car.rb
Creating car no. 1:-604682514
Creating car no. 2:-604682524
Creating car no. 3:-604682564

Listing cars:
Car no. 3:-604682564
Car no. 2:-604682524
Car no. 1:-604682514

Creating car no. 4:-604682654
Creating car no. 5:-604682644

Listing cars:
Car no. 4:-604682654
Car no. 5:-604682644
Car no. 3:-604682564
Car no. 2:-604682524
Car no. 1:-604682514

Sleeping...
Firing gc.

Listing cars:
Car no. 5:-604682644
Car no. 1:-604682514