Hi...
I d like to know if there is a way to force garbage collection of objects (still referenced)... I often need that when triing to connect ot a database for instance... If it fails, the connection object is still in memory
Thanks
Cédrick
Hi Cédrick,
Welcome to the list. This is a pretty difficult question. There are a number of answers and all of them have the potential of doing some damage.
In general, if you want an object to be taken to the garbage, you need to break all links to strong objects. Then you can force a garbage collection by running: Utilities garbageCollectAndReport.
What is a strong reference you ask? That is anything that is not a weak reference. You can hold onto an object using a weakArray but when the garbage collector comes around she can pull it right outa there. So, simply nil-ing out references to your object and closing it (since an inspector or even the debugger has a strong reference to it), should allow the garbage collector to clean things up for you.
Databases are another animal all together. If you pull something from a database that has another object attached to it, say a person holds onto an address, then the database can not simply pull in every connection because in most cases that would mean pulling in the entire database on every call. So instead databases implement something called a Proxy. A Proxy is a stand-in for an object and it gets de-proxified when the object is touched. So in my example having a person object with and address ivar, if I dont look at the ivar, (starts to feel like quantum mechanics huh), then the address is a proxy, which tells the database where to get the actual address object. Now in this case you can usually get rid of the object without breaking the link, by sending proxyify or becomeProxy, or sometimes Ive seen zap. These methods are implemented by your db provider and you will find it on the database object that all your database objects inherit from.
Ok from your question it would seem to me that you have a connection object, not a persistent data object that just wont go away. You could find the references to that object and nil them out. This is the preferred method. You could look at the clean up code on that object and see if you can figure out how the database vendor does it. Methods like close, cleanUp, disconnect, or something like that will give you and idea of what they wanted to do if it hadnt blown up on you. Follow the path that you would normally go down for disconnecting when you dont blow up.
Now for the really dangerous, not for the faint of heart, back up your entire computer before you even read this, there is become: !
(are you scared?) Become says change this object ID into an object ID of something else! This is how proxies usually work. The database grabs and instantiates an object from disk then it tells the proxy to become the newObject. (aProxy become: newObject). In this case everybody is happy cause nobody wants a proxy they want the new object. Now kids dont try this at home! You can force a garbage collect of your connection object by doing aConnectionObject become: String new. The issues here are pretty simple, you could type this wrong and blow away your whole String class. You could leave your database objects looking for a connection on an empty string. But if as you say it is broken anyway, it cant get worse!
Ok now before I go I have to tell you a story. I worked with a lovely object database that persisted string literals passed out of methods. A method that contains a string compiles that string into a literal and uses that reference internally but you could send it out and make it persistent on my lovely object database.
For example try this:
On some class create the method
Object class >> ron
Return a string literal
^Ron is a great guy
Then do this
Object ron at: 11 put: $e.
Object ron at: 13 put: $k.
Object ron at: 14 put: $y.
Ok so now look at the method ron it hasnt changed, but when you print Object ron, you get something completely different, and not very flattering either. This is because the method contains a string literal.
So when my database grabbed my string literal and made it persistent it meant that I couldnt open the methods in a browser until connected to the database! Be careful of string literals. My colleagues still make fun of me because I always put a copy after a string literal.
Ron
^Ron is a great guy copy
So that I never pass out a modifiable literal!
Ok enough of that I hope that helps!
Happy Coding!!
Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
Ron@USMedRec.com
_____
From: cdrick Sent: Tuesday, May 09, 2006 10:42 AM
Hi...
I d like to know if there is a way to force garbage collection of objects (still referenced)... I often need that when triing to connect ot a database for instance... If it fails, the connection object is still in memory
Thanks
Cédrick
Hi Ron and thanks for that answer ;)
sure this list is a cool thing ;-)
In general, if you want an object to be taken to the garbage, you need to
break all links to strong objects. Then you can force a garbage collection by running: Utilities garbageCollectAndReport.
I do it but doesnt change size a lot :)
What is a strong reference you ask? That is anything that is not a weak
reference. You can hold onto an object using a weakArray but when the garbage collector comes around she can pull it right outa there. So, simply nil-ing out references to your object and closing it (since an inspector or even the debugger has a strong reference to it), should allow the garbage collector to clean things up for you.
cool. I ve always wandered what it was :). I still dont see really well how it works but I'll have a look to it. A weak array then store object with weak references and then when GC come over, it removes the references ???
Ok from your question it would seem to me that you have a connection object, not a persistent data object that just won't go away. You could find the references to that object and nil them out. This is the preferred method. You could look at the clean up code on that object and see if you can figure out how the database vendor does it. Methods like close, cleanUp, disconnect, or something like that will give you and idea of what they wanted to do if it hadn't blown up on you. Follow the path that you would normally go down for disconnecting when you don't blow up.
I try to look at that before, but often when connection fails, it remains an object... etc that was why :) (maybe local variables of workspace are keeping references...)
I ll see with pointers... the thing is I dont really feel the difference between object pointing to this value chase pointers and explore pointers
Now for the really dangerous, not for the faint of heart, back up your
entire computer before you even read this, there is become: ! (are you scared?) Become says change this object ID into an object ID of something else! This is how proxies usually work. The database grabs and instantiates an object from disk then it tells the proxy to become the newObject. (aProxy become: newObject). In this case everybody is happy cause nobody wants a proxy they want the new object. Now kids don't try this at home! You can force a garbage collect of your connection object by doing aConnectionObject become: String new. The issues here are pretty simple, you could type this wrong and blow away your whole String class. You could leave your database objects looking for a connection on an empty string. But if as you say it is broken anyway, it can't get worse!
tried that once :) dangerous :) I ll wait a bit lol
Ok so now look at the method ron it hasn't changed, but when you print Object ron, you get something completely different, and not very flattering either. This is because the method contains a string literal.
cool example :)
Thanks for all Ron
Am 09.05.2006 um 16:41 schrieb cdrick:
Hi...
I d like to know if there is a way to force garbage collection of objects (still referenced)...
A still referenced object is never garbage-collected. You must cut the reference first, that is, write another object (like nil) into the variable that references your object.
Since it is a bit unpredictable *when* the garbage collector will collect your object after it is not referenced anymore, you can force a GC by "Smalltalk garbageCollect". However, this is mostly useful as an aid in debugging. Only when doing very specific tasks it is necessary to force a GC by code.
- Bert -
I d like to know if there is a way to force garbage collection of objects (still referenced)...
A still referenced object is never garbage-collected. You must cut the reference first, that is, write another object (like nil) into the variable that references your object.
not so easy :) especially when I explore or inspect to see pointers :) It's propably better to use a workspace...
Stop pointing to it. It will go away on its own. ie
conn := PGConnection new connect. conn isConnected ifFalse: [conn := nil]. "Reference gone - object collected"
On Tuesday, May 09, 2006, at 07:41AM, cdrick cdrick65@gmail.com wrote:
<<Original Attached>>_______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Cedrick have a look at PointerExplorer, PointerFinder.
Stef On 9 mai 06, at 16:41, cdrick wrote:
Hi...
I d like to know if there is a way to force garbage collection of objects (still referenced)... I often need that when triing to connect ot a database for instance... If it fails, the connection object is still in memory
Thanks
Cédrick _______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
beginners@lists.squeakfoundation.org