How to understand why object is not collected?

Discussion in 'Ruby' started by Victor \Zverok\ Shepelev, Oct 28, 2006.

  1. Hi all.

    Here's a problem.

    I have some object of MyClass with complex "freeing" logic, and I want to
    test this logic.
    I do:

    span = .... #somehow created object

    ObjectSpace.define_finalizer(span, proc{p "gc ok"}) #define test finalizer

    span.detach #remove object from all of my internal caches, no references
    to object should exist

    span = nil #remove the last reference to object

    GC.start #<===HERE the object must be collected and finalized

    p "end of code"

    I expect:
    "gc ok"
    "end of code"

    I receive:
    "end of code"
    "gc ok"

    OK, I suppose there are some references to the object still exists. I want
    to know, at least, what number of references still exists (in ideal, I'd
    want to know, where they are).
    How I can? (except of harcode hacking GC's C code)

    Ruby 1.9 (downloaded a week ago), Windows.


    Victor \Zverok\ Shepelev, Oct 28, 2006
    1. Advertisements

  2. This is probably a situation where GC is being conservative. A simple

    class Foo; end

    foo =
    foo = nil


    p ObjectSpace.each_object(Foo) {} # ==> 1

    Probably this means that the Foo instance pointer is still visible
    somewhere in the local frame.

    But that doesn't mean that there is a leak:

    class Foo; end

    10.times do


    p ObjectSpace.each_object(Foo) {} # ==> 1

    In my experience, it's hard to write precise unit tests for GC behavior,
    and you end up with some fuzziness. The important property of GC is
    really the asymptotic behavior.
    Joel VanderWerf, Oct 28, 2006
    1. Advertisements

  3. From: Joel VanderWerf [mailto:]
    Sent: Saturday, October 28, 2006 10:52 PM
    OK, I've got it.
    Just for now, I need no precise unit test. I just want to know, would the
    objects of MyClass collected in principle. Can I achieve the goal somehow?

    Victor \Zverok\ Shepelev, Oct 28, 2006
  4. --yahdd2r5OMEJJ+pI
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: inline
    Content-Transfer-Encoding: quoted-printable

    Hard to say what is going wrong but the solution is simple. Whenever
    you have a resource that must be released, do it explicitly. The way
    this is usually implemented is either:

    f =3D 'foo'

    Or, more conveniently'foo') {|f| puts}

    The block-form uses ensure to make sure the file handle gets closed.

    Content-Type: application/pgp-signature
    Content-Disposition: inline

    Version: GnuPG v1.4.5 (FreeBSD)

    -----END PGP SIGNATURE-----

    Eero Saynatkari, Oct 28, 2006
  5. From: Eero Saynatkari [mailto:]
    Sent: Saturday, October 28, 2006 11:20 PM
    I know this (I was C++ guy foe many years, so RAII is my breath), but can't
    My objects are HTML DOM elements and I want to be sure they are GC'd when
    detached from DOM and have no other references.

    Victor \Zverok\ Shepelev, Oct 28, 2006
  6. What about creating a lot of them in a loop, without keeping references?
    Then I would expect GC to leave at most one instance.
    Joel VanderWerf, Oct 28, 2006
  7. From: Joel VanderWerf [mailto:]
    Sent: Saturday, October 28, 2006 11:26 PM
    They can't be created by .new, they created in correspondence to some HTML
    DOM by C extension.
    Problem already solved by the trick:

    def test
    span = ....
    ObjectSpace.define_finalizer(span, proc{p "gc ok"})
    span = nil



    p "end of code"

    Output corresponds to my expectations (gc ok => end of code)

    Thanks for your help!

    Victor \Zverok\ Shepelev, Oct 28, 2006
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.