Appendix C - Memory Management Issues
The Macintosh memory model is based on the concept
of the heap: an area of memory where items are placed as they are needed. Items
are placed on the heap in the
first available space when they are created, and the spaces which were occupied
by deleted items are returned to the heap and made available for new items. Pointers
or Handles (pointers to pointers) are directed at the items when they are
placed on the heap. The Memory Manager part of the Operating System deals with
all program and system requests for creation and deletion of handles, pointers
and blocks. Memory blocks on the Macintosh come in two types: relocatable and
non-relocatable ones.
fig. C.1 - A pointer to a non-relocatable block.
A pointer to a non-relocatable
block never changes since the block itself cannot move (see figure
C.1).
fig. C.2 - A handle to a relocatable block.
A pointer to a
relocatable block can change since the block can move (see figure C.2). For this
reason the memory manager will maintain a single non-relocatable master pointer
to every relocatable block. This master pointer is created when the block itself
is created, and is made to
point to it. If the block needs to be moved, the value in the master pointer
is modified appropriately by the memory manager. The use of handles allows the
memory manager to consolidate free areas by compacting the heap. This involves
moving relocatable blocks together to avoid the fragmentation of the heap with
spaces which are too small to be of any further use, or by moving items pointed
to by handles into appropriate places. Having non-relocatable blocks causes "islands"
to be created in the heap,
which can help to cause fragmentation. For this reason handles are used as
much as possible, in preference to pointers, and any permanent non-relocatable
blocks are created early in a program's execution, since this will mean that they
are low down in the heap and hence less likely to get in the way of relocatable
blocks being created and destroyed. One potential problem with relocatable
blocks comes when such a block is being accessed when the memory manager starts
compacting the heap, and thus
moves the block. We will look at a situation where this may occur. Pascal defines
a statement "with", which allows access to structures without recourse to continually
specifying the full "path" to the structure. Figure C.3 shows a sample
program which will encounter an error at run-time, or at least produce spurious
results.
program testprog;
type
myDataStructure = record
I1:integer;
I2:integer;
AStr:Str255;{a string of 255 characters}
TheData:array [1..40] of integer;
end;
myDataPtr:^myDataStructure;{a pointer to such a structure}
myDataHndl: ^myDataPtr;{a handle to such a structure}
var
mydata:myDataStructure;
myHndl:myDataHndl;
myptr:pointer;
begin
{create a handle to a relocatable block large enough to hold mydata}
myHndl:=myDataStructure(NewHandle(SizeOf(MyDataStructure)));
with myHndl^^ do {de-reference the handle to get the record components}
begin
I1:=10;
myPtr:=NewPtr(20000);{a large non-relocatable block gets created here}
{and now it's possible that the handle to myDataStructure has moved}
I1:=I1+50;{and this line may well corrupt memory, since although}
{the handle is pointing somewhere else, the with statement }
{de-referenced the handle in advance - before it was moved by the}
{memory manager.}
end;{of the "with" stuff}
end.
fig. C.3 Pascal program in which a moving handle causes an error.
In
this case, the
relocatable block moved while it was being accessed, and the method of access (using
with), meant that the address of the block was calculated in
advance of the block moving, rendering those addresses invalid when the block
finally moved. In order to avoid this problem it is possible to get the Memory
Manager to "lock" a relocatable block to prevent it from moving, and a programmer
must be wary of accessing unlocked relocatable blocks. In order to get the least
possible memory fragmentation,
relocatable blocks should only be locked when necessary, and then unlocked
when they are no longer currently in use.
back to Appendix B. forward to Appendix D