Can someone explain what a "weak" vs (I am guessing) "strong" reference is? I have been struggling with Garbage Collection for quite some time now and saw this on another list:
"You'll need to add an instance variable to process and modify fork to record the origin. Currently processes don't remember their ancestor. I recommend you create a special fork that remembers ancestry, rather than modifying the default fork. You will potentially accumulate a lot of garbage otherwise. Also, you might consider making the reference from a process to its parent weak to allow the parent to be GC'ed when it terminates even if it has children." I, too, am maintaining parent/child relationships in my application and have just been doing something like:
Parent>>createChild |child|
child := Child new parent: self. ^child I am assuming, given my troubles, that this is NOT a weak reference?! Thank you, Rob
_______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Sun, Jul 13, 2008 at 6:15 PM, Rob Rothwell <[hidden email]> wrote:
> Can someone explain what a "weak" vs (I am guessing) "strong" reference is? [snip] > I, too, am maintaining parent/child relationships in my application and have > just been doing something like: > Parent>>createChild > |child| > child := Child new parent: self. > ^child > I am assuming, given my troubles, that this is NOT a weak reference?! Hi Rob, Have a look at the class comment on WeakArray: "WeakArray is an array which holds only weakly on its elements. This means whenever an object is only referenced by instances of WeakArray it will be garbage collected." My understanding of this is that garbage collection is done by reference counting, and so the situation you described may result in parent and child forming a circular reference to each other, and so never being collected - but it depends on what you do with that return value. I note that there are very few uses of any Weak* classes in the image, so it's likely that there is a better way of implementing what you're aiming for; eg the child could drop its direct parent reference, and do something like Child>>parent ^ Parent allInstances detect: [ :each | each children includes: self ] (or vice versa depending on which way you're more likely to traverse the relationship). This is just me thinking out loud though - perhaps someone else could comment on best practice in this case. "Smalltalk Best Practice Patterns" is very useful in answering these types of questions, but my copy is in a box somewhere at the moment. Hope this helps, Michael _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
>>>>> "Michael" == Michael Davies <[hidden email]> writes:
Michael> I note that there are very few uses of any Weak* classes in the image, Michael> so it's likely that there is a better way of implementing what you're Michael> aiming for; eg the child could drop its direct parent reference, and Michael> do something like Child> parent Michael> ^ Parent allInstances detect: [ :each | each children includes: self ] Michael> (or vice versa depending on which way you're more likely to traverse Michael> the relationship). I'd argue though that a solution that involves #allInstances has a bit of code smell. For example, consider an XML node, looking for its parent. In a given parsed document, you'll likely have thousands of nodes, and it would be clearly inefficient to continually find the one parent by asking all of them. In that case though, weak refs probably weren't needed anyway, since each node can just contain its parent. Michael> This is just me thinking out loud though - perhaps someone else could Michael> comment on best practice in this case. "Smalltalk Best Practice Michael> Patterns" is very useful in answering these types of questions, but my Michael> copy is in a box somewhere at the moment. Absolutely. A clearly seminal book. My dog-eared copy is within reach, at least when I'm in my home office. Too bad Kent has gone off to the Java, and now C# realm, if I heard right. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Michael Davies-2
Hello Michael,
Child>>>parent MD> ^ Parent allInstances detect: [ :each | each children includes: self ] allInstances scans *every* object in the image which is slow. The garbage collector needs a path to a root object (whatever that is) so a purely circular reference does not prevent garbage collection of parent and child. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Rob Rothwell
A weak reference is simply a reference that will not prevent an object
from being garbage collected. It is common to use a weak reference in back pointers when you know you are having circularities. It is practically a pattern, when building a hierarchy of objects, to make the parent pointer in parent child type structures a weak reference. So how do you make a weak reference? You stick a WeakArray in as a holder. So in your parent/child objects you would write something like: Node>>parent ^ parent ifNotNil: [parent first] ifNil: [parent] Node>>parent: p parent := p ifNotNil: [WeakArray with: p] ifNil: [p] thus using a WeakArray as a holder for the parent. When a weak reference gets garbage collected, its weak references are set to nil first. On Jul 13, 2008, at 9:15 AM, Rob Rothwell wrote: > Can someone explain what a "weak" vs (I am guessing) "strong" > reference is? I have been struggling with Garbage Collection for > quite some time now and saw this on another list: > > "You'll need to add an instance variable to process and modify fork > to record the origin. Currently processes don't remember their > ancestor. I recommend you create a special fork that remembers > ancestry, rather than modifying the default fork. You will > potentially accumulate a lot of garbage otherwise. Also, you might > consider making the reference from a process to its parent weak to > allow the parent to be GC'ed when it terminates even if it has > children." > > I, too, am maintaining parent/child relationships in my application > and have just been doing something like: > > Parent>>createChild > |child| > child := Child new parent: self. > ^child > > I am assuming, given my troubles, that this is NOT a weak reference?! > > Thank you, > > Rob > > _______________________________________________ > Beginners mailing list > [hidden email] > http://lists.squeakfoundation.org/mailman/listinfo/beginners _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
On Mon, Jul 14, 2008 at 11:42 AM, Todd Blanchard <[hidden email]> wrote:
So how do you make a weak reference? You stick a WeakArray in as a holder. So in your parent/child objects you would write something like: Thank you! This is what I wanted to know; I'll give this a try, and see how it works for me...
So many Classes, so little time... Rob _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Herbert König
On Mon, Jul 14, 2008 at 4:43 PM, Herbert König <[hidden email]> wrote:
> Hello Michael, > > > Child>>>parent > MD> ^ Parent allInstances detect: [ :each | each children includes: self ] > > allInstances scans *every* object in the image which is slow. Ouch, I can see that it would be :-) > The garbage collector needs a path to a root object (whatever that is) > so a purely circular reference does not prevent garbage collection of > parent and child. Thanks, that's interesting - does that mean that the parent-child linkage in Rob's example isn't the root cause of his problem? _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Rob Rothwell
Am 14.07.2008 um 09:51 schrieb Rob Rothwell: > On Mon, Jul 14, 2008 at 11:42 AM, Todd Blanchard > <[hidden email]> wrote: > So how do you make a weak reference? You stick a WeakArray in as a > holder. So in your parent/child objects you would write something > like: > > Node>>parent > ^ parent ifNotNil: [parent first] ifNil: [parent] > > Node>>parent: p > parent := p ifNotNil: [WeakArray with: p] ifNil: [p] > > thus using a WeakArray as a holder for the parent. > > When a weak reference gets garbage collected, its weak references > are set to nil first. > > Thank you! This is what I wanted to know; I'll give this a try, and > see how it works for me... > > So many Classes, so little time... Well, Todd certainly knows when he needs to introduce weak refs but a simple parent-child relation (say, in a tree) is *not* a good example for this. The parent reference in a child does not prevent it from being garbage-collected, unless there exist other references to it. You cut the child link and it's gone. But if there are indeed other references to the child weak refs would just mask the problem because the parent may get garbage-collected but the child is not. The problem in that case typically is not the parent/child links but those other references. In a clean design you very rarely need weak refs. Also, you need to sprinkle your code with ifNil: tests because a weak ref can become nil any time. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Michael Davies-2
Hello Michael,
MD> Thanks, that's interesting - does that mean that the parent-child MD> linkage in Rob's example isn't the root cause of his problem? see Bert's reply, he knows why it is so, I only know that I do it all the time (circular links) and it never prevents GC. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Michael Davies-2
On Mon, 14 Jul 2008 12:07:51 +0200
"Michael Davies" <[hidden email]> wrote: > On Sun, Jul 13, 2008 at 6:15 PM, Rob Rothwell <[hidden email]> wrote: > > Can someone explain what a "weak" vs (I am guessing) "strong" reference is? > [snip] > > I, too, am maintaining parent/child relationships in my application and have > > just been doing something like: > > Parent>>createChild > > |child| > > child := Child new parent: self. > > ^child > > I am assuming, given my troubles, that this is NOT a weak reference?! > > Hi Rob, > Have a look at the class comment on WeakArray: "WeakArray is an array > which holds only weakly on its elements. This means whenever an object > is only referenced by instances of WeakArray it will be garbage > collected." > > My understanding of this is that garbage collection is done by > reference counting, and so the situation you described may result in > parent and child forming a circular reference to each other, and so > never being collected - but it depends on what you do with that return > value. Squeak's garbage collector is a generational mark/sweep garbage collector. It does not use reference counting. http://wiki.squeak.org/squeak/1469 (unfortunately the page has a dead URL in it). Gulik. -- Michael van der Gulik <[hidden email]> _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Bert Freudenberg
On Mon, Jul 14, 2008 at 10:43:30PM -0700, Bert Freudenberg wrote:
> > In a clean design you very rarely need weak refs. Also, you need to > sprinkle your code with ifNil: tests because a weak ref can become nil > any time. It is also worth mentioning that weak references can lead to performance problems, particularly if you use a lot of them. The process of cleaning up weak references happens in the background, and is not very efficient if a lot of weak references need to be scanned. The end result is that your Squeak image will gradually become very slow, for no obvious reason. Bert's observation on design is the best reason to avoid using weak references, but if you need more convincing, consider performance ;) Dave _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
All that sounds like "don't use weak reference" :)
Cédrick _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Hello cdrick,
c> All that sounds like "don't use weak reference" :) .... unless you know exactly what you are doing. -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by cedreek
On Tue, Jul 15, 2008 at 2:39 PM, cdrick <[hidden email]> wrote:
> All that sounds like "don't use weak reference" :) > > > Cédrick > A nice clear summary! Thanks to all who have posted on this topic - it's been a very useful discussion. Michael _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by cedreek
One of the uses of weak references in other languages is to keep a collection of all the instances of a class without preventing them being garbage collected. Obviously, this is not necessary in squeak.
On 7/15/08, Herbert König <[hidden email]> wrote: Hello cdrick, _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Am 15.07.2008 um 06:42 schrieb Marcin Tustin:
> One of the uses of weak references in other languages is to keep a > collection of all the instances of a class without preventing them > being garbage collected. Obviously, this is not necessary in squeak. One major use in Squeak is for ensuring that system resources (such as file handles) are released when a file object is garbage-collected. Note this is only a fall-back, you should still use #close on files, but to prevent resource leakage in odd cases, a weak reference is held to each open file. It's one of the low-level implementation details that exist to make the normal live of a Smalltalk programmer simpler. Only the framework designer interfacing to non-Smalltalk objects (such as files) needs to worry about it. I've never seen a need for weak references in application-level code. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
In reply to this post by Herbert König
>>>>> "Herbert" == Herbert König <[hidden email]> writes:
Herbert> Hello cdrick, c> All that sounds like "don't use weak reference" :) Herbert> .... unless you know exactly what you are doing. One possible use I haven't seen in this thread is to "keep notes" on a class you don't own (and don't want to change), without preventing them from being GC'ed normally. For example, if I wanted to write a system watcher that noticed the comings and goings of Process objects, I'd likely keep a Dictionary keyed by the Process instance referencing the data of start times. However, I wouldn't want that key to keep the Process instance from being gc'ed, so I'd use a weak dictionary. This is how the classic "dependents" system works as well: the dependencies are in a WeakDictionary so that when the watched object goes away, the dependencies are also cleaned. The alternative is to add a set of properties to the Process that others can stuff information, so that "Process allInstances" can get my process watcher what it needs instead. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Hello Randal,
RLS> dictionary. This is how the classic "dependents" system works as well: the RLS> dependencies are in a WeakDictionary so that when the watched object goes RLS> away, the dependencies are also cleaned. thanks for some free education (no smiley, I mean it), now I'll do some homework and look up dependency. I use it in some places without knowing of it's "weakness". -- Cheers, Herbert _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Am 15.07.2008 um 08:26 schrieb Herbert König: > Hello Randal, > > RLS> dictionary. This is how the classic "dependents" system works > as well: the > RLS> dependencies are in a WeakDictionary so that when the watched > object goes > RLS> away, the dependencies are also cleaned. > > thanks for some free education (no smiley, I mean it), now I'll do > some homework and look up dependency. > > I use it in some places without knowing of it's "weakness". The dependents are weak only for "regular" objects. Proper Models handle their own dependents collection in a non-weak manner. - Bert - _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Bert Freudenberg a écrit :
> > Am 15.07.2008 um 08:26 schrieb Herbert König: > >> Hello Randal, >> >> RLS> dictionary. This is how the classic "dependents" system works as >> well: the >> RLS> dependencies are in a WeakDictionary so that when the watched >> object goes >> RLS> away, the dependencies are also cleaned. >> >> thanks for some free education (no smiley, I mean it), now I'll do >> some homework and look up dependency. >> >> I use it in some places without knowing of it's "weakness". > > > The dependents are weak only for "regular" objects. Proper Models handle > their own dependents collection in a non-weak manner. > > - Bert - Hmm, not really "Warning: this example is stupid!" | tmp | tmp := Model new. tmp addDependent: #x. tmp addDependent: #y. tmp dependents class. "=> DependentsArray" DependentsArray is a class that holds weakly to its elements... The difference is that the DependentsArray itself don't have to pollute the global WeakIdentityKeyDictionary (Object classPool at: #DependentsFields). But maybe we have just quit the beginners rails... Nicolas _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |