Discussion:
[Newbies] Weakly holding and circular references
Tm Jhnsn
2018-04-29 13:35:51 UTC
Permalink
Hi all,

I've tried to learn how to properly use Weak collections for purposes of
circular references, but I'm not sure I fully understand -- not enough
to actually use it in my implementation.

I made a fairly large project a couple of years ago where I ended up
with a lot of stale information in the image because I had circular
references keeping objects from being cleared by GC.  I learned my
lesson, and addressed the situation by building a 'release' mechanism
and explicitly tearing down objects when I was done with them.

From what I understand, the Weak collection hierarchy will keep
references to objects but not in such a way that the GC won't clear them.

If I have, say, an ArchiveItem object, and the ArchiveItem has
ArchivedFiles, but I want ArchivedFiles to know which ArchiveItem they
belong to, then I've set myself up with a circular reference situation.

I understand I could have a separate object which allows ArchivedFiles
to *ask* which ArchiveItem they belong to, instead of storing it within
themselves.

But I also understand that I could potentially use, say, a WeakSet in
ArchiveItem, which will hold weakly onto ArchivedFiles since the
ArchivedFiles themselves refer back to the ArchiveItem. I get the
impression that this approach would free me from having to build out a
complete 'release' mechanism or from doing other explicit clearing and
removal of references.  But I don't understand if I could find myself in
a situation where an ArchiveItem thinks it doesn't have any
ArchivedFiles because they got GCed before I was truly through with them.

Can anyone recommend any approach or any materials on this subject?

Thanks,
Tim
Ron Teitelbaum
2018-04-29 17:19:47 UTC
Permalink
Hi Tim,

Thanks for your email. I believe you may be thinking of this backward.
The piece you want to pay careful attention is where the strong references
are. Objects will be cleared when they have no more strong references.
What is worse than having an object stick around is having it GC'd because
there is nothing left to hold onto it. Also, it doesn't matter how many
connections the objects have to each other if they are disconnected from
the running object tree they go poof (or should).

There are a lot of ways to hold onto objects but it's usually part of a
model that is referenced when you start your program running. Things
attached to that model stay around. You can also hold onto objects by
using class variables or something else more permanent, but this usually is
not necessary and is better left for static objects like something that
configures your application.

If you have an object with a circular reference and it's not held on to by
anything else it all goes poof.

The question you have to answer when you have this situation is what's
holding onto my object? You can use the pointer finder. On an instance of
your class (MyClass allInstances) right click and select, Explore pointers.

You will probably find an object in your model that is still holding onto
it. It's that pointer you need to remove. Having a method like #delete
that tears down all the references to your model is the right way to go.
When you find more pointers you forgot about when you designed your model
you add a method to break the pointers there.

There are places where a WeakArray is useful. Usually when you need to
reference something that might later go away. Something like a background
process is a good example. Say you fork a method and want to know if that
process is still running. You can hold onto it with a WeakArray and then
check to see if that process is still in the collection. When the process
stops it will get GC'd and removed from the WeakArray or it may still be
there but marked as Terminated (until it's GC'd later).

You are much better off designing your model with strong references in mind
in a way that makes it easy to understand what objects are still active and
which are not. Removing connections to objects that are no longer needed
is easier when you design the model that way. Use WeakArrays only when you
are holding onto objects that you know are disappearing, or being modified
by something else that later removes pointers, like a Cache. If you need
to hold onto the array for some reason you don't want that array to
accidentally hold all of your objects. This is not the usual case and in
most cases what you want is a regular Collection.

Does that help?

All the best,


*Ron Teitelbaum*
*Chief Executive Officer*
*3D Immersive Collaboration Consulting****@3Dicc.com
Follow Me On Twitter: @RonTeitelbaum <https://twitter.com/RonTeitelbaum>
www.3Dicc.com <http://www.3dicc.com/>
https://www.google.com/+3Dicc
Post by Tm Jhnsn
Hi all,
I've tried to learn how to properly use Weak collections for purposes of
circular references, but I'm not sure I fully understand -- not enough to
actually use it in my implementation.
I made a fairly large project a couple of years ago where I ended up with
a lot of stale information in the image because I had circular references
keeping objects from being cleared by GC. I learned my lesson, and
addressed the situation by building a 'release' mechanism and explicitly
tearing down objects when I was done with them.
From what I understand, the Weak collection hierarchy will keep references
to objects but not in such a way that the GC won't clear them.
If I have, say, an ArchiveItem object, and the ArchiveItem has
ArchivedFiles, but I want ArchivedFiles to know which ArchiveItem they
belong to, then I've set myself up with a circular reference situation.
I understand I could have a separate object which allows ArchivedFiles to
*ask* which ArchiveItem they belong to, instead of storing it within
themselves.
But I also understand that I could potentially use, say, a WeakSet in
ArchiveItem, which will hold weakly onto ArchivedFiles since the
ArchivedFiles themselves refer back to the ArchiveItem. I get the
impression that this approach would free me from having to build out a
complete 'release' mechanism or from doing other explicit clearing and
removal of references. But I don't understand if I could find myself in a
situation where an ArchiveItem thinks it doesn't have any ArchivedFiles
because they got GCed before I was truly through with them.
Can anyone recommend any approach or any materials on this subject?
Thanks,
Tim
_______________________________________________
Beginners mailing list
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Ben Coman
2018-04-29 21:51:16 UTC
Permalink
Post by Tm Jhnsn
Hi all,
I've tried to learn how to properly use Weak collections for purposes of
circular references, but I'm not sure I fully understand -- not enough to
actually use it in my implementation.
I made a fairly large project a couple of years ago where I ended up with
a lot of stale information in the image because I had circular references
keeping objects from being cleared by GC. I learned my lesson, and
addressed the situation by building a 'release' mechanism and explicitly
tearing down objects when I was done with them.
Note that since the VM uses a tracing garbage collector rather than
reference counting, circular references *only* between objects 'a' and 'b'
will not in themselves prevent them both being garbage collected. They
will only stick around if one of them has a chain of references through
from a root object.

cheers -ben

Loading...