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