|
Smalltalk/X WebserverDocumentation of class 'WeakArray': |
|
|
Class: WeakArrayInheritance:Object | +--Collection | +--SequenceableCollection | +--ArrayedCollection | +--WeakArray
Description:
WeakArrays can be used to trace disposal of objects; in contrast to other
objects, references by WeakArrays will NOT keep an object from being
garbage collected.
Instead, whenever an object kept in a WeakArray dies, its entry is set to a SmallInteger,
and the WeakArray is informed by the storage manager. The WeakArray itself
then informs possible dependents via the dependency mechanism.
WeakArrays are used to track disposal of objects which keep external
world resources. For example, FileStreams must close their underlying
file when disposed (otherwise you could run out of OS filedescriptors).
This can be done by keeping the FileStream objects in a weakArray, and
keep a parallel array of filedescriptors. Whenever a fileStream is
freed, search both arrays for an index where the stream is set to a SmallInteger, but the
filedescriptor is non-nil. Then close that file, and nil the filedescriptor
entry. Notice, that there is a class (Registry) which does exactly this in
a more programmer friendly way.
Another application is caching of data: keep it in a weakArray, so the
data in that cache will not be unreclaimable due to being cached.
(for example, the ResourcePack class uses a WeakArray to cache recently
used resource data for a while).
The way in which weakArrays get informed by the runtime system is via
an interrupt (DisposeInterrupt) which is first sent to the disposeHandler
(typically ObjectMemory). ObjectMemory then takes the required steps to
notify all weakArrays via the #lostPointer message.
The reason for not sending messages directly from the VM is to make it
possible to run the finalization code at lower priority or from another class.
Also, as a side effect, it is possible to delay finalization by blocking
interrupts. (thus, the actual sending of the #lostPointer message is under
control of Smalltalk code, which is modifyable).
A weakArray notifies its dependents via normal dependency notfications.
As a possible option, we could perform the weakArray scanning only in
the oldSpace reclamation code - this would remove most of the overhead,
but will lead to much longer delayed finalization .... we will see.
[instance variables:]
dependents get informed via #change notifiction
that the weakArray has lost pointers.
Having the dependents here is an optimization.
[class variables:]
RegistrationFailedSignal raised if a weakArray cannot be
registered by the VM. This only happens,
if the VM has to resize its internal tables
and is running out of malloc-memory.
[memory requirements:]
OBJ-HEADER + (size * ptr-size) + ptr-size
+ sizeof(dependents-collection)
Hints:WeakArray handling adds small some overhead to the VM (each weakarray is scanned after each GC). It is uncertain, if the current mechanism works well with (say) ten-thousands of weakArrays. We had the system running with >2000 weakArrays, some being quite big for a while and had a few percent of added gc time. The system as delivered creates between 50 and 100 weakArrays, but with many dependents, this number may grow. If you need the dependency mechanism on a huge number of objects, consider adding a (non-weak) dependents field to your class - take the implementation of Model as a guide (or subclass them from Model). Related information:
Array
WeakIdentitySet
WeakIdentityDictionary
Registry
Model
Class protocol:initialization
Instance protocol:GC registration
|
|
|
ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Wed, 17 Dec 2025 08:31:25 GMT
|