Question about finalize

class Foo
  
  def finalize
      puts "finalize"
  end
end
Foo.new

didn’t output anything
I tried add GC.collect, still nothing,
seemed finalize doesn’t get called?

Also, does struct has finalize?

Ultimately it just means that the GC doesn’t want/need to garbage collect that instance in this contrived example. Structs aren’t allocated by the GC so no.

class Mortals
  def finalize
      puts "i am #{object_id}. My life is beautiful. Goodbye!"
  end
end

100000.times do
  Foo.new
end
crystal build m.cr
./m | wc -l
for i in {1..5}; do ./g | wc -l; done
99600
99738
97157
99547
96646

It seems that in some cases the end of the world will come while we are still alive!

2 Likes

This happens because the GC doesn’t run at program exit - if there is memory still allocated then the system is responsible for deallocating stuff, and the finalizer won’t get invoked. Finalizers should basically only be used in code dealing with C extensions that need them to help with cleaning up stuff in long running programs.

Personally I wish finalizers were run as part of shutting down, but there are a lot of potential issues around that that makes can be really hard to deal with.

1 Like

Related: Finalize objects on program exit · Issue #13995 · crystal-lang/crystal · GitHub

Amos has some good advice for what happens when your program exits

5 Likes