FFI ExternalStructure - proper memory cleanup
John M McIntosh
johnmci at smalltalkconsulting.com
Sat Jan 20 23:48:36 UTC 2007
On Jan 20, 2007, at 2:53 PM, Jim McLoughlin wrote:
> Thanks for any help, apologies if this is more appropriate for the
> beginners list.
>
> cheers,
>
> Jim M
>
Doing this correctly is a complex question
If you look at MPEGFile you'll see a pattern of using weak object
that I used a number of years back.
The class has an class variable Registry
Class side methods
registry
register:
unregister:
are used to register and unregister: instances
when an instance is created or destroyed
register
and unregister instance side methods are used to place or remove the
object in the Registry class variable.
On register, a shallowcopy of the instance is created which is held
onto by the Registery weakly. When the
original instance is garbage collected, the weak entry will be
finalized.
An important issue here is that the instance variables in the copy
did not create a circular reference to
the original, which will prevent the copy from being Gced. see
StandardFileStream>actAsExecutor
Usually one does not have an issue, you'll know because your copy
instance won't go away if you do.
Usually then when you explicity destroy your instance, you would
invoke unregister to remove the instance
from the weak array registery.
On finalization the copy instance is sent finalize where you would do
any cleanup required like the destroy of external
resources, and unregisterExternalObject:
As for the external address. You'll also note in the MPEGFile we do
fileIndex := Smalltalk registerExternalObject: fileBits.
self register.
when we create the instance
The registerExternalObject: is registering the results of a primitive
call in a special VM table that is cleared when
the VM is restarted. Later we use the Smalltalk externalObjects
at:ifAbsent: to get the bits out of the VM Table using the fileIndex
value we remember . I'll note since it's slot based it could return
bits from something else, so that is why we check against fileBits.
self fileHandle = fileBits ifTrue: [Smalltalk
unregisterExternalObject: fileIndex].
fileHandle
(Smalltalk externalObjects at: fileIndex ifAbsent: [^nil]) == fileBits
ifTrue: [^fileBits]
ifFalse: [^nil].
You can of course as earlier noted have a class side startup method
an nil out instance vars for all instances when the VM is started...
--
========================================================================
===
John M. McIntosh <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
========================================================================
===
More information about the Squeak-dev
mailing list
|