Important: The information in this document is obsolete and should not be used for new development.
About the Memory Manager
The Memory Manager is the part of the Macintosh Operating System that controls the dynamic allocation of memory space. Ordinarily, you need to access information only within your own application's heap, stack, and A5 world. Occasionally, however, you might need to use the Memory Manager to allocate temporary memory outside of your application's partition or to initialize new heap zones within your application partition. You might also need to read a system global variable to obtain information about the environment in which your application is executing.The Memory Manager provides a large number of routines that you can use to perform various operations on blocks within your application partition. You can use the Memory Manager to
The Memory Manager also provides routines that you can use to access areas of memory outside your application partition. You can use the Memory Manager to
- set up your application partition
- allocate and release both relocatable and nonrelocatable blocks in your
application heap- copy data from nonrelocatable blocks to relocatable blocks, and vice versa
- determine how much space is free in your heap
- determine the location of the top of your stack
- determine the size of a memory block and, if necessary, change that size
- change the properties of relocatable blocks
- install or remove a grow-zone function for your heap
- obtain the result code of the most recent Memory Manager routine executed
This section describes the areas of memory that lie outside your application partition.
- allocate memory outside your partition that is currently unused by any open application or by the Operating System
- allocate memory in the system heap
It also describes multiple heap zones.Temporary Memory
In the Macintosh multitasking environment, your application is limited to a particular memory partition (whose size is determined by information in the'SIZE'
resource of your application). The size of your application's partition places certain limits on the size of your application heap and hence on the sizes of the buffers and other data structures that your application can use.If for some reason you need more memory than is currently available in your application heap, you can ask the Operating System to let you use any available memory that is not yet allocated to any other application. This memory, called temporary memory, is allocated from the available unused RAM; in general, that memory is not contiguous with the memory in your application's zone
Your application should use temporary memory only for occasional short-term purposes that could be accomplished in less space, though perhaps less efficiently. For example, if you want to copy a large file, you might try to allocate a fairly large buffer of temporary memory. If you receive the temporary memory, you can use the large buffer to copy data from the source file into the destination file. If, however, the request for temporary memory fails, you can instead use a smaller buffer within your application heap. Although the use of a smaller buffer might prolong the copy operation, the file is nonetheless copied.
One good reason for using temporary memory only occasionally is that you cannot assume that you will always receive the temporary memory you request. For example, if two or more applications use all available memory outside the system partition, then a request by any of them for some temporary memory would fail.
Another strategy for using temporary memory is to use it, when possible, for all nonessential memory requests. For example, you could allocate window records and any associated window data using temporary memory. This scheme allows you to keep your application partition relatively small (because you don't need space for nonessential tasks) but assumes that users will not fill up the available memory with other applications.
Multiple Heap Zones
A heap zone is a heap (that is, an area in which you can dynamically allocate and release memory on demand) together with a zone header and a zone trailer. The zone header is an area of memory that contains essential information about the heap, such as the number of free bytes in the heap and the addresses of the heap's grow-zone function and purge-warning procedure. The zone trailer is just a minimum-sized block placed as a marker at the end of the heap zone. (See "Heap Zones" on page 2-19 for a complete description of zone headers and trailers.)When your application is executing, there exist at least two heap zones: your application's heap zone (created when your application was launched) and the
system heap zone (created when the system was started up). The system heap zone is the heap zone that contains the system heap. Your application heap zone (also known
as the original application heap zone) is the heap zone initially provided by the Memory Manager for use by your application and any system software routines your application calls.Ordinarily, you allocate and release blocks of memory in the current heap zone, which by default is your application heap zone. Unless you change the current heap zone (for example, by calling the
InitZone
orSetZone
procedures), you do not need to worry about which is the current zone; all blocks that you access are taken from the current heap zone, that is, your application heap zone.Occasionally, however, you might need to allocate memory in the system heap zone. System software uses the system heap to store information it needs. Although, in general, you should not allocate memory in the system heap, there are several valid reasons for doing so. First, if you are implementing a system extension, the extension can use the system heap to store information. Second, if you want the Time Manager or Vertical Retrace Manager to execute some interrupt code when your application is not the current application, you might in certain cases need to store the task record and the task code in the system heap. Third, if you write interrupt code that itself uses heap memory, you should either place that memory in the system heap or hold it in real RAM to prevent page faults at interrupt time, as discussed in the chapter "Virtual Memory Manager" in this book.
You can create additional heap zones for your application's own use by calling the
InitZone
procedure. If you do maintain more than one heap zone, you can find out which heap zone is the current one at any time by calling theGetZone
function, and you can switch zones by calling theSetZone
procedure. Almost all Memory Manager operations implicitly apply to the current heap zone. To refer to the system heap zone or to the (original) application heap zone, you can call the functionsSystemZone
orApplicationZone
. To find out which zone a particular block resides in, you can call theHandleZone
function (if the block is relocatable) or thePtrZone
function (if it's nonrelocatable).
Once you have created a heap zone, it remains fixed in size and location. For this reason, it usually makes more sense to use the undivided application heap zone for all of your memory-allocation needs. You might, however, choose to initialize an additional heap zone in circumstances like these:
- WARNING
- Be sure, when calling routines that access blocks, that the zone in which the block is located is the current zone. If, for example, you attempt to release an empty resource in the system zone when the current zone is not the system zone, the Operating System might incorrectly update the list of free master pointers in your partition.
Before deciding to create additional heap zones, however, make sure that you really need to. Maintaining multiple heap zones requires a considerable amount of extra work. You must always make sure to allocate or release memory in the correct zone, and you must monitor memory conditions in each zone so that your application doesn't run out
- If you are implementing a software development environment and want to launch applications within the development environment's partition, you can initialize a heap zone for the launched application to use as its heap zone.
- If you want to avoid heap fragmentation but cannot prevent allocation of small nonrelocatable blocks in the middle of your program's execution, you could, soon after your application starts up, allocate a small heap zone to hold the nonrelocatable blocks you allocate during execution.
- If you need to resize a particular handle quite often, you can minimize the resizing time by creating a heap zone whose size is set to the maximum size the handle will ever be assigned. Because there is only one relocatable block in the new heap zone, the resizing is likely to happen more quickly than if that block were in the original heap zone (where other relocatable blocks in the zone might need to be moved).
of memory.The System Global Variables
Just as the Toolbox stores information about your drawing environment in a set of QuickDraw global variables within your application partition, the Operating System and Toolbox store information about the entire multiple-application environment in a set of system global variables, also called low-memory global variables. The system global variables are stored in the lowest part of the physical RAM, in the system partition.Most system global variables are intended for use by system software only, and you should never need to read or write them directly. Current versions of system software contain functions that return values equivalent to most of the important system global variables. Use those routines whenever they are available. However, you might occasionally need to access the value of a system global variable to maintain compatibility with previous versions of system software, or you might need to access a system global variable whose value no equivalent function returns.
The MPW interface file
SysEqu.p
defines the memory locations at which system global variables are stored in the latest version of system software. For example,SysEqu.p
contains lines like these:
CONST RndSeed = $156; {random number seed (long)} Ticks = $16A; {ticks since last boot (unsigned long)} DeskHook = $A6C; {hook for painting desktop (pointer)} MBarHeight = $BAA; {height of menu bar (integer)}You can use these memory locations to examine the value of one of these variables. See "Reading and Writing System Global Variables" on page 2-8 for instructions on reading and writing the values of system global variables from a high-level language.You should avoid relying on the value of a system global variable whenever possible. The meanings of many global variables have changed in the past and will change again in the future. Using the system global variables documented in Inside Macintosh is fairly safe, but you risk incompatibility with future versions of system software if you attempt to access global variables defined in the interface files but not explicitly documented.
Even when Inside Macintosh does document a particular system global variable, you should use any available routines to access that variable's value instead of examining it directly. For example, you should use the
TickCount
function to find the number of ticks since startup instead of examining theTicks
global variable directly.
- IMPORTANT
- You should read or write the value of a system global variable only when that variable is documented in Inside Macintosh and when there is no alternate method of reading or writing the information you need.