I have this object, X, I want to delete (typically from within the context
of some other object Y). So I remove it from Y (set some Y instVar to nil, or remove it from some collection instVar of Y). I mark X 'deleted'. Now I have to make sure that no other objects retain any (effective) reference to X. What are some best practices for doing this? My current thought: 1. Every accessor of every instVAr for all relevant objects can do a check-and-clean before returning a value. AnyClass>>aSingleObjAccessor singleInstVar isDeleted ifTrue: [singleInstVar := nil]. ^ singleInstVar AnyClass>>aCollectionAccessor collInstVar removeIf: [:x | x isDeleted]. ^collInstVar 2. Perhaps I should also use weak-refs to X wherever possible, so X could be GC'd before all its incoming refs are check-and-cleaned? How does one actually do this? I suspect I am missing far more elegant solutions. All pointers :-) appreciated. Thanks - Sophie |
On 27/02/2008, itsme213 <[hidden email]> wrote:
> I have this object, X, I want to delete (typically from within the context > of some other object Y). So I remove it from Y (set some Y instVar to nil, > or remove it from some collection instVar of Y). I mark X 'deleted'. > > Now I have to make sure that no other objects retain any (effective) > reference to X. > > What are some best practices for doing this? > Never give out reference to X from Y, so any objects expect Y simply can't have it. That's the best practice. > My current thought: > 1. Every accessor of every instVAr for all relevant objects can do a > check-and-clean before returning a value. > > AnyClass>>aSingleObjAccessor > singleInstVar isDeleted ifTrue: [singleInstVar := nil]. > ^ singleInstVar > > AnyClass>>aCollectionAccessor > collInstVar removeIf: [:x | x isDeleted]. > ^collInstVar > > 2. Perhaps I should also use weak-refs to X wherever possible, so X could be > GC'd before all its incoming refs are check-and-cleaned? How does one > actually do this? > > > I suspect I am missing far more elegant solutions. > > All pointers :-) appreciated. > your app. That's the whole point of automatic memory management: you should not care how many references point to particular object. GC cares for you. -- Best regards, Igor Stasenko AKA sig. |
"Igor Stasenko" <[hidden email]> wrote in message
> Never give out reference to X from Y, so any objects expect Y simply > can't have it. That's the best practice. Often true, but (part of) my app has to build a graph of objects. I'm not looking trying to build a destructor or finalizer for GC, but more for some form of referential integrity. - Sophie |
In reply to this post by Igor Stasenko
> > I suspect I am missing far more elegant solutions. > > > > All pointers :-) appreciated. > > > If you raised this question, i think you missed something in design of > your app. That's the whole point of automatic memory management: you > should not care how many references point to particular object. GC > cares for you. > > -- > Best regards, > Igor Stasenko AKA sig. > Cheers, Sebastian |
In reply to this post by Sophie424
On Feb 26, 2008, at 3:48 PM, itsme213 wrote: > I have this object, X, I want to delete (typically from within the > context > of some other object Y). So I remove it from Y (set some Y instVar > to nil, > or remove it from some collection instVar of Y). I mark X 'deleted'. Well first I'll note if you use weak logic the deal is the object that is only weak referenced will be deleted sometime in the future, where the future is milliseconds or maybe days, well maybe not days, but if you expect milliseconds, then 5 seconds can kill you. This is related usually to how the GC does with cleaning up weak reference and how it interacts with the smalltalk code which usually runs to do the finalization which in Squeak isn't robust enough to deal with 10,000's of objects. Now to be clever you could use PointerFinder pointersTo: anObject except: objectsToExclude or variations of become: We have discussions back and forth (no resolution yet) about finding things in Sophie given *limited* memory for book object, well like a weak value dictionary that when an object needs data looks into by holding on to the uuid. If found or needs to load, we load into the weak dictionary later when all the owners get GCed, then the object will at some point disappear. Well that or storing the data in cache limited to N MB and always doing a lookup when you need to use the data, so the owner only holds the key not the data. I note in Sophie we can make the entire Sophie system *disappear* because we gone to great pains to ensure removal of certal SophieClass instances and references in the right places make the entire Sophie system GC-able. -- = = = ======================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com = = = ======================================================================== |
"John M McIntosh" <[hidden email]> wrote
> Well first I'll note if you use weak logic the deal is the object that is > only weak referenced will > be deleted sometime in the future, where the future is milliseconds or > maybe days, well maybe not > days, but if you expect milliseconds, then 5 seconds can kill you. If all other accessors check-and-remove any item that has been marked as deleted then such a delay would be non-critical (I think). In my case, the weak-ref is only a relatively minor possible optimization, my main question is about ref-integrity when an object is deleted, so other objects do not visibly behave as though they still had references to it. Thanks - Sophie |
In reply to this post by Sebastian Sastre-2
"Sebastian Sastre" <[hidden email]> wrote
> But for the rest of common objects references in the image you just > abandon them > and they will GC'd automagically. I did not phrase my first question clearly, sorry. My problem is not about reclaiming the "deleted" object, but about making sure no other objects behave (visibly) as though they still had references to it. Thanks - Sophie |
Ok, well in the finalization you can broadcast to everyone who had an
interest that the object has died. Some system signal using the proxy cloned object. An example in sophie is where the storage subsystem instance is deleted, the proxy then ensure any files are closed and temp files deleted, and notifies the Memory based storage subsystem any cached streams for this particular storage subsystem can be deleted. A pattern used is to register interest in an object, then on finalization sending I'm dead messsage to those interested parties. I'll let someone else give details. usually the ugly thing with this register/free pattern is someone forgets to send the free message or super free etc. Then although you *know* you've *deleted* that object you find you have 10,000 of them lurking one friday afternoon usually before a holiday. On Feb 26, 2008, at 8:22 PM, itsme213 wrote: > "Sebastian Sastre" <[hidden email]> wrote > >> But for the rest of common objects references in the image you just >> abandon them >> and they will GC'd automagically. > > I did not phrase my first question clearly, sorry. My problem is not > about > reclaiming the "deleted" object, but about making sure no other > objects > behave (visibly) as though they still had references to it. > > Thanks - Sophie -- = = = ======================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com = = = ======================================================================== |
In reply to this post by Sophie424
I can't help feeling that you're barking up the wrong tree here. If
you have references to some object then by definition it will not get garbage collected. Once there are no more references, then *poof* away it goes. Why are you worrying about objects getting 'deleted'? The only thing you seem to have said that seems to offer us any useful info here is a mention of a graph of objects; and the same rule applies - as long as there are references it must continue to exist. Now you might be thinking that references within the graph will stop it getting GC'd but in fact there must be references that trace back to a set of root objects. If you, for example, made a global and had it be a reference to one object in a circular linked list then the list would stay alive. As soon as you set the global to point to some other object (outside the circle) then the circle would be dead, barring any contexts on your execution stack having a reference still alive. The fact that objects in the circle reference one another would not prevent the garbage collector doing its work. More explanations of what is worrying you would probably help us to explain things to you. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim The best packed information most resembles random noise. |
In reply to this post by Sophie424
So, If I understand you, you have a graph of object that refer to each
other and you want to remove an object from that graph? You have two relatively straightforward choices: 1. Have the object mark itself as deleted, and then ensure that all clients of that object test its status before using it. 2. Do a (depth first) walk of the entire graph whenever you delete an object to remove it. The problem with 1 is the object may never get GC'ed. If you use weak references that will help, except now it might get GC'ed to early. A solution is to hold the objects in some global structure with hard references and remove it from their when done with it. Also, a perhaps bigger problem is you may forget the write the test code at some point and break the protocol. The problem with 2 is that it will be expensive every time you remove an object. Those are your trade offs. itsme213 wrote: > I have this object, X, I want to delete (typically from within the context > of some other object Y). So I remove it from Y (set some Y instVar to nil, > or remove it from some collection instVar of Y). I mark X 'deleted'. > -- Jeffrey Straszheim http://straszheim.50megs.com |
Free forum by Nabble | Edit this page |