Article View: fj.lang.st80
Article #30Smalltalk Textbook 48 (in English)
From: AOKI Atsushi
Date: Wed, 20 Mar 1996 00:00
Date: Wed, 20 Mar 1996 00:00
326 lines
13607 bytes
13607 bytes
Hello,
"WeakReference & Finalization (Smalltalk Textbook 48)" is
available via WWW. This leaves us only one chapter "Smalltalk
OOP (Smalltalk Textbook 49)".
http://sracog.srainc.com/~aoki/SmalltalkTextbook/index.html
For one's information, please let us attach the 48th chapter
to this post.
Thanks,
AOKI Atsushi, Hayashi Kaoru, and Brent Reeves
smalltalker@srainc.com
..._ .. ... .._ ._ ._.. .. _.._ . .__ .... .. ._. ._.. . _.. .
WeakReference & Finalization (Smalltalk Textbook 48)
WeakReference and Finalization may be unfamiliar to most
Smalltalkers because they are related to garbage collection.
You do not need to know about them to write ordinary
Smalltalk programs. But as soon as you have need to
communicate with another Smalltalk system or handle external
objects such as operating system resources, you'll need to
understand them. And at this point in this text, it is good
to understand them before proceeding.
Garbage collection is a mechanism to crate free space for new
objects by deleting and collecting the memory used by objects
which are no longer needed. In Smalltalk you can ignore
memory allocation and deallocation because objects which are
no longer needed are automatically garbage collected. In C++
you must manage memory space yourself via free, delete,
constructors and destructors.
Even though garbage collection is automatic, you may invoke
it explicitly. Evaluate the next expression and the mouse
icon should change to a trash can for a brief time while
garbage is being collected.
------------------------------------------------------------
ObjectMemory garbageCollect
------------------------------------------------------------
This next message prints some information about garbage or
free space during garbage collection.
------------------------------------------------------------
ObjectMemory verboseGlobalCompactingGC
------------------------------------------------------------
There are several ways to invoke garbage collection. Please
refer to the 'collecting garbage' category of the
'ObjectMemory' class.
Garbage collection deletes only unused objects; never
necessary objects. Necessary objects are those linked by a
'StrongReference' from system roots like a global dictionary
or context. 'StrongReference' is an object pointer (aka OOP)
which is like an address for an object in the memory space.
If you create an object (instance of a class) then store it
in another object (e.g. OrderedCollection), an OOP is stored
rather than the object.
Another type of OOP is called a 'WeakReference'. I would
like to describe it presently, but it is difficult to
describe without preparation. So, first of all let me give
you a metaphor as an introduction to 'WeakReference' and
'Finalization' (commonly associated with 'WeakReference').
Suppose the president of a company has a son-in-law. Suppose
also that he gives this person a job, even though the
son-in-law is incompetent. Nobody can get rid of the
son-in-law because he is related to the president
(WeakReference). Now suppose the president makes a few bad
decisions at a time when business is down. The board of
directors will fire the president and reorganize
(Finalization) the company. Now the incompetent son-in-law no
longer has connections (WeakReference) and he is let go.
'WeakReference' and 'Finalization' behave like to this story.
Let's say object X has a 'StrongReference' to object A and a
'WeakReference' to object B. Then if object A is somehow
deleted for 'Finalization', object X, which only has a
'WeakReference' to object B, will also be deleted. A
'WeakReference' is not enough to keep object X around.
Here is another example. Suppose there is a collection and
objects A, B and C. C stores the collection. B is an element
of the collection. And B is also referred to by A. The
situation is :
-----------------------------------------------------------
C --StrongReference --> a collection
a collection --WeakReference --> B
A --StrongReference --> B
-----------------------------------------------------------
If A unlinks its 'StrongReference' to B for any reason, then
B is subject to garbage collection. Sooner or later garbage
collection will be activated and B will disappear from the
collection.
By having a 'WeakReference' to an object, you are indicating
that it is ok if the object dissappears.
'Finalization' is the name of the phase when garbage
collection is invoked. And in our example, when B is deleted,
a message is sent to the collection informing it of the
demise of B.
Evaluate Program 48-1 to see an example of what happens to
items only linked by a weak reference, in this case a 'WeakArray':
Program 48-1: (WeakArray, ObjectMemory; gc, finalization,
garbage collection)
------------------------------------------------------------
| weakArray |
weakArray := WeakArray new: 3.
weakArray at: 1 put: 'aaa' copy.
weakArray at: 2 put: 'bbb' copy.
weakArray at: 3 put: 'ccc' copy.
weakArray inspect.
ObjectMemory garbageCollect
------------------------------------------------------------
Even though you can see that ('aaa' 'bbb' 'ccc') are stored
in the array, the inspector inidicates the values of the
first three items in the array are all zero. This is because
garbage collection reclamed their space.
If you store 'aaa' in a 'WeakArray', the literal 'aaa' will
have a 'StrongReference' to the 'WeakArray' from the literal
frame of the method execution context. Therefore Program 48-1
uses a 'copy' rather than the literal itself to illustrate
how objects can disappear.
The program invokes garbage collection explicitly. It is not
really necessary, because 'aaa', 'bbb', and 'ccc', which were
borne in Eden have only a short life and will be collected by
the generation scavenger and not even be moved to current
memory space.
Program 48-2 opens two inspector Windows, one is for
'strongArray' (Array) and another is for 'weakArray' (WeakArray).
Program 48-2: (WeakArray Array ObjectMemory; gc,
finalization, garbage collection)
------------------------------------------------------------
| strongArray weakArray |
strongArray := Array new: 3.
strongArray at: 1 put: 'aaa' copy.
strongArray at: 2 put: 'bbb' copy.
strongArray at: 3 put: 'ccc' copy.
weakArray := WeakArray withAll: strongArray.
strongArray inspect.
weakArray inspect.
ObjectMemory garbageCollect
------------------------------------------------------------
This time you see 'aaa', 'bbb', 'ccc' in both the weak and
the strong array. Actually they are the very same objects.
Now evaluate this next message expressions in the right sub
window of the 'strongArray' (Array) inspector.
------------------------------------------------------------
self at: 1 put: nil.
self at: 2 put: nil.
self at: 3 put: nil.
ObjectMemory garbageCollect
------------------------------------------------------------
The 'self' of the above messages is a 'strongArray ' (an
instance of Array), so the contents of 'strongArray ' become
(nil nil nil). The contents of 'weakArray ' (an instance of
WeakArray) should now also be (0 0 0) because references of
'weakArray' are unlinked automatically references from the
'strongArray' are unlinked.
Program 48-3 is implemented for the above A,B,C objects
example. Notice that C is a dependent object of the
collection. And also notice that C can receive a message for
B's death. Do it the program.
Program 48-3: (WeakArray Array ValueHolder PluggableAdaptor
ObjectMemory; gc, finalization, garbage collection)
------------------------------------------------------------
| foo collection bar blee blue |
foo := 'aaa' copy.
blue := 'bbb' copy.
collection := WeakArray with: foo with: blue.
bar := PluggableAdaptor on: collection.
bar
getBlock: [:model | false]
putBlock: [:model :value | false]
updateBlock:
[:model :aspect :parameter |
Transcript cr; show: 'Aspect:', aspect printString.
aspect = #ElementExpired
ifTrue:
[Transcript cr.
Transcript show: 'Element has died.'.
Transcript show: ' Model: ', model printString].
false].
collection addDependent: bar.
blee := ValueHolder with: foo.
blee inspect.
bar inspect.
ObjectMemory garbageCollect
------------------------------------------------------------
Two inspectors are raised. Verify that the following links
exist. Notice that the collection has a 'WeakReference' to
foo and blue.
---------------------------------------------------------------
bar (aPluggableAdaptor) -- model ---> collection (aWeakArray)
collection (aWeakArray) -- at: 1 ---> foo ('aaa')
-- at: 2 ---> blue ('bbb')
blee (aValueHolder) -- value ---> foo ('aaa')
---------------------------------------------------------------
Soon after the inspectors are raised, you should see
Element has died. Model: WeakArray ('aaa' 0)
in the Transcript window. Now we will unlink the
'StrongReference' from blee to foo. Evaluate the following in
the right sub window of the inspector for blee (ValueHolder).
------------------------------------------------------------
self value: nil.
ObjectMemory garbageCollect
------------------------------------------------------------
'Element has died.' will print in the Transcript window
indicating that the Pluggable Adaptor received an update
message from the garbage collector. Step by step what
happened is:
1) A unlinks its reference to B
2) B becomes subject to garbage collection
3) Garage collection is activated
4) B is removed from the collection to which C refers
5) A message of B's removal is broadcast
'WeakReference' and 'Finalization' should be clear enough now
for you to understand Program 48-4 without too much trouble.
Program 48-4: (WeakArray Array ValueHolder PluggableAdaptor
ObjectMemory; gc, finalization, garbage collection)
------------------------------------------------------------
| foo collection blee bar |
foo := Array
with: 'aaa' copy
with: 'bbb' copy
with: 'ccc' copy.
collection := WeakArray withAll: foo.
blee := PluggableAdaptor on: collection.
blee
getBlock: [:model | false]
putBlock: [:model :value | false]
updateBlock:
[:model :aspect :parameter |
aspect = #ElementExpired ifTrue: [model
nilAllCorpsesAndDo:
[:i |
Transcript cr.
Transcript show: 'Element'.
Transcript show: i printString.
Transcript show: ' has died.']].
false].
collection addDependent: blee.
bar := ValueHolder with: foo.
bar inspect.
blee inspect.
ObjectMemory garbageCollect
------------------------------------------------------------
After Program 48-4, evaluate the following expressions in the
right sub window of the inspector of A (ValueHolder).
------------------------------------------------------------
self value at: 1 put: 'ddd'.
self value at: 2 put: 'eee'.
self value at: 3 put: 'fff'.
ObjectMemory garbageCollect
------------------------------------------------------------
Notice this time that the contents of the collection to which
C refers are not (0 0 0) but (nil nil nil). The key is in the
implementation of the 'nilAllCorpsesAndDo:' message. You can
'Browse Implementors Of...' to see that it sets each deleted
item to nil.
By using inspectors, you have been able to observe the birth,
growth, illness, death, and corpse of an object in keeping
with the metaphor of a company mentioned above. In a manner
of speaking 'WeakReference' corresponds to illness,
'Finalization' corresponds to death and a zero OOP
corresponds to a corpse.
As a final example of 'WeakReference' and 'Finalization',
imagine a resource management program for the host window
system. Resource object examples are instances of
ScheduledWindow, Pixmap and Mask. The resources of the host
window system are temporarily lent to user applications and
must eventually be returned to the host window system.
However while a resource is in use by the application, it can
not be returned. In other words the resources must only be
returned when no one is using them. 'WeakReference' and
'Finalization' are a convenient way to handle this situation
in which you want to manage a resource while it is being
used, and then release it. It is a necessary mechanism for
distributed parallel systems. You can see how it can control
the birth and death of external objects which are distributed
over a network.
There are two other classes related to 'WeakReference':
'WeakKeyAssociation' and 'WeakDictionary'. Experiment with
your own classes to handle 'WeakReference'.
Copyright (C) 1994-1996 by Atsushi Aoki
Translated by Kaoru Rin Hayashi & Brent N. Reeves
..._ .. ... .._ ._ ._.. .. _.._ . .__ .... .. ._. ._.. . _.. .
Technical Details
Message-ID:
<aoki-2003961337040001@sraco6.srainc.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 145144,ef0ddb60afd0b71f,start X-Google-Attributes: gid145144,public From: aoki@sra.co.jp (AOKI Atsushi) Subject: Smalltalk Textbook 48 (in English) Date: 1996/03/20 Message-ID: <aoki-2003961337040001@sraco6.srainc.com> X-Deja-AN: 144207721 organization: Software Research Associates, Inc. newsgroups: fj.lang.st80