57
Chapter 8 Memory Use Memory Use

Chapter 8 Memory Use. Chapter 8 -- Memory Use2 In this chapter we will consider memory use during compilation and run time. During compilation, the

Embed Size (px)

Citation preview

Page 1: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8

Memory UseMemory Use

Page 2: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 2

In this chapter we will consider memory use In this chapter we will consider memory use during compilation and run time.during compilation and run time.

During compilation, the principal memory-use During compilation, the principal memory-use problem is the management of the symbol problem is the management of the symbol table.table.

But the compiler must also lay the groundwork But the compiler must also lay the groundwork for how data will be stored and accessed for how data will be stored and accessed during program execution.during program execution.

Page 3: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 3

1. The Symbol Table

The symbol table is consulted at almost every The symbol table is consulted at almost every point in the compilation process.point in the compilation process.

The main issue in symbol table design is The main issue in symbol table design is organizationorganization

We will consider the gross organization of the We will consider the gross organization of the table and then questions of how the structure of table and then questions of how the structure of the source program influences the structure of the source program influences the structure of the symbol table.the symbol table.

Page 4: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 4

1.1 Organization

A symbol table can be organized as a simple A symbol table can be organized as a simple array, a linked list, a binary search tree, or an array, a linked list, a binary search tree, or an array accessed by hashing.array accessed by hashing. The choice of structure is a trade-off between The choice of structure is a trade-off between

memory requirements and access speed.memory requirements and access speed. Since the symbol table will typically be Since the symbol table will typically be

consulted thousands of times in the course of consulted thousands of times in the course of compiling a program, speed of access is compiling a program, speed of access is generally given first priority.generally given first priority.

Page 5: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 5

The simplest organization is the array.The simplest organization is the array.

The advantages of using an array are:The advantages of using an array are: simplicity simplicity and economy of storage.and economy of storage.

The disadvantages are:The disadvantages are: the limited size of the table the limited size of the table and the time it takes to search the table.and the time it takes to search the table.

Page 6: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 6

A linked list offers only two advantages over A linked list offers only two advantages over an array.an array. First, it is expandableFirst, it is expandable Second, using self-organizing storage can speed Second, using self-organizing storage can speed

search considerably.search considerably. Self-organizing storage is described in Sedgwick’s Self-organizing storage is described in Sedgwick’s

textstexts Basically, you move accessed members to the front Basically, you move accessed members to the front

of the list, since their access will probably come of the list, since their access will probably come again soon.again soon.

Page 7: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 7

A binary search tree offers quicker access to A binary search tree offers quicker access to data items.data items. It offers the minor subsidiary advantage that if It offers the minor subsidiary advantage that if

the table is to be listed at the end of the table is to be listed at the end of compilation, it can be displayed in alphabetical compilation, it can be displayed in alphabetical order by a simple in-order traversal.order by a simple in-order traversal.

Its main drawback is increased memory Its main drawback is increased memory consumption (2 pointers), and the fact that consumption (2 pointers), and the fact that deleting items tends to unbalance it and deleting items tends to unbalance it and increase search time.increase search time.

Page 8: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 8

Most compilers use hashed storage.Most compilers use hashed storage. Usually hashing with chaining.Usually hashing with chaining. The array size is limited, but the linked-lists can The array size is limited, but the linked-lists can

be any length.be any length. The search time is The search time is OO(k), where k is the length (k), where k is the length

of the listof the list k is also the number of items stored in the table k is also the number of items stored in the table

divided by the size of the array, so you can set a divided by the size of the array, so you can set a bound on it.bound on it.

Page 9: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 9

1.2 Storing Identifiers

Storing variable names can present special difficulties.Storing variable names can present special difficulties. In FORTRAN, variable names are generally limited to In FORTRAN, variable names are generally limited to

eight characters, and it is no great problem to provide eight characters, and it is no great problem to provide an eight character field in the symbol-table record.an eight character field in the symbol-table record.

BUT, many modern languages support very long BUT, many modern languages support very long variable names (31 is a frequent limit), and that can variable names (31 is a frequent limit), and that can waste space in an array implementation if you have i, j, waste space in an array implementation if you have i, j, and k used.and k used.

Page 10: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 10

One compromise is to allow very long One compromise is to allow very long identifiers but recognize only the first six or identifiers but recognize only the first six or eight characters.eight characters.

Or, if you must store the entire name, Or, if you must store the entire name, Use dynamic memoryUse dynamic memory or have a big array for names, and have the or have a big array for names, and have the

symbol table point to the start of the name, with symbol table point to the start of the name, with some marker at the end. some marker at the end.

This represents a cheap and optimal way of storing This represents a cheap and optimal way of storing them.them.

Page 11: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 11

Page 12: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 12

1.3 Record Formats

Symbol-table records must include either the Symbol-table records must include either the identifier name or a pointer to the name, and a identifier name or a pointer to the name, and a code indicating the data type of the object to code indicating the data type of the object to which the entry refers. Beyond that, the which the entry refers. Beyond that, the contents of the record may vary widely.contents of the record may vary widely.

It follows that it is probably not a good idea to It follows that it is probably not a good idea to use a uniform format for all symbol-table use a uniform format for all symbol-table entries. entries.

Page 13: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 13

1.4 Special Problems

In a language like FORTRAN, this is virtually In a language like FORTRAN, this is virtually all there is to symbol-table management.all there is to symbol-table management. Find a suitable organization,Find a suitable organization, Decide on record formatsDecide on record formats Perhaps concoct a hashing function Perhaps concoct a hashing function -- and you are done-- and you are done

But other languages present additional But other languages present additional problems.problems.

Page 14: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 14

Block-structured languages with static scope Block-structured languages with static scope rules, like Algol, Pascal, PL/I, and C, have to rules, like Algol, Pascal, PL/I, and C, have to model the scope rules in the symbol table.model the scope rules in the symbol table.

In addition, these languages permit records, In addition, these languages permit records, and again the symbol table must be designed to and again the symbol table must be designed to facilitate the handling of these structures.facilitate the handling of these structures.

Page 15: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 15

Scope Rules:Scope Rules: There are two basic approaches to There are two basic approaches to

implementing scope rules in the symbol table.implementing scope rules in the symbol table. You can have a separate table for each scopeYou can have a separate table for each scope You can have a global table in which each identifier You can have a global table in which each identifier

is marked with the scope to which it belongs.is marked with the scope to which it belongs.

It is probably easier to have a separate table for It is probably easier to have a separate table for each scope. Then you treat it like a stack.each scope. Then you treat it like a stack.

Page 16: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 16

Problems with using a stackProblems with using a stack If you have a multi-pass compilerIf you have a multi-pass compiler If you need to generate cross-reference tablesIf you need to generate cross-reference tables

• where a variable was definedwhere a variable was defined

• every place it was usedevery place it was used

Such tables are typically generated at the end of Such tables are typically generated at the end of compilation, but at that time all the stack entries compilation, but at that time all the stack entries have been deleted. So it may be necessary to save have been deleted. So it may be necessary to save these symbol tables for later use when they are these symbol tables for later use when they are “popped” off the stack.“popped” off the stack.

Page 17: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 17

Records:Records: A new record is in many ways like a new A new record is in many ways like a new

scope.scope. Identifier names in a record may be duplicates of Identifier names in a record may be duplicates of

other identifier names used outside the record, just other identifier names used outside the record, just as they may in scopes.as they may in scopes.

(Code pg 286)(Code pg 286)

Page 18: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 18

Therefore, you have the choice Therefore, you have the choice creating a subtable for the record, just as we would creating a subtable for the record, just as we would

for a new scope and hang it off the record’s nodefor a new scope and hang it off the record’s node add the record’s fields to the symbol-table with a add the record’s fields to the symbol-table with a

flag/pointer to the record to whom they belong.flag/pointer to the record to whom they belong. 8.3a & 8.3b8.3a & 8.3b

Page 19: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 19

2. Run-Time Memory Management

We can classify the use of memory We can classify the use of memory management during execution as static or management during execution as static or dynamic.dynamic.

In static memory management, storage for all In static memory management, storage for all variables is allocated at compile time.variables is allocated at compile time. FORTRAN, COBOLFORTRAN, COBOL allows no recursion, but is easy to do.allows no recursion, but is easy to do.

Page 20: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 20

In dynamic memory management, storage is In dynamic memory management, storage is found for the variables at run time as it is found for the variables at run time as it is needed.needed.

The main issues in dynamic memory The main issues in dynamic memory management are management are using a stack for variable storage using a stack for variable storage and supporting dynamic memory allocation for and supporting dynamic memory allocation for

statements like statements like newnew and and deletedelete

Page 21: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 21

2.1 Static Memory Management

This is the oldest and simplest scheme.This is the oldest and simplest scheme. every variable is assigned an address when the every variable is assigned an address when the

program is translated.program is translated. Advantage: It is simple, and requires minimal Advantage: It is simple, and requires minimal

overhead.overhead. Disadvantage: No recursion. Disadvantage: No recursion.

Page 22: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 22

Addresses for variables may be specified asAddresses for variables may be specified as absolute memory locations, absolute memory locations, or they may be given as offsets from some or they may be given as offsets from some

reference address.reference address. If you specify the addresses relative to a If you specify the addresses relative to a

reference address, the program can go reference address, the program can go anywhere in memory -- it is anywhere in memory -- it is relocatable.relocatable. Architectures with segmented memory usually Architectures with segmented memory usually

require relative addresses.require relative addresses. Many programming languages allow a mix of Many programming languages allow a mix of

static and dynamic allocation.static and dynamic allocation.

Page 23: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 23

2.2 Dynamic Memory Management: Recursion In dynamic memory management, memory In dynamic memory management, memory

addresses are not fixed (bound) until run time.addresses are not fixed (bound) until run time.

We use this approach to support recursive We use this approach to support recursive subprograms and to permit dynamic allocation subprograms and to permit dynamic allocation of memory. of memory.

Page 24: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 24

Recursive Subprograms:Recursive Subprograms: A recursive subprogram is one that calls itself, A recursive subprogram is one that calls itself,

either directly or indirectly.either directly or indirectly. When recursive subprograms are used, we refer When recursive subprograms are used, we refer

to each call as an instantiation, or to each call as an instantiation, or activationactivation.. If the subprogram has local variables, the old If the subprogram has local variables, the old

values of these variables must be saved before values of these variables must be saved before the recursive call so that the new activation the recursive call so that the new activation won’t wipe them out.won’t wipe them out.

Page 25: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 25

Saving these variables means that memory Saving these variables means that memory must be allocated for each activation. must be allocated for each activation.

And when each activation terminates, its local And when each activation terminates, its local variables must be jettisoned so that the variables must be jettisoned so that the variables for the previous activation will be in variables for the previous activation will be in effect again.effect again.

We manage this by means of a stack. The thing We manage this by means of a stack. The thing pushed on the stack is called an activation pushed on the stack is called an activation recordrecord

it provides storage for all the local variablesit provides storage for all the local variables it usually includes other things as well, such as:it usually includes other things as well, such as:

• parameters being passed.parameters being passed.• the return address of the subprogram that called it.the return address of the subprogram that called it.

Page 26: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 26

Any time a subprogram needs to access a Any time a subprogram needs to access a variable, it looks in the topmost activation variable, it looks in the topmost activation record on the stack. If it is a local variable it record on the stack. If it is a local variable it will be there.will be there.

If it needs a non-local variable, one that is If it needs a non-local variable, one that is “scoped in” from some other procedure, then it “scoped in” from some other procedure, then it must find that in the activation record for the must find that in the activation record for the block that owns the variable.block that owns the variable.

Let’s look at example of this with a recursive Let’s look at example of this with a recursive function to compute factorial values.function to compute factorial values.

Page 27: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 27

Page 28: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 28

Suppose we call fact(2). The stack of Suppose we call fact(2). The stack of activation records looks like this before the call.activation records looks like this before the call.

Page 29: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 29

When we call fact, an activation record for that When we call fact, an activation record for that call goes on the stack:call goes on the stack:

Page 30: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 30

In order to access lim, Fact uses the s.c.p or In order to access lim, Fact uses the s.c.p or Static Chain Pointer to know where the Static Chain Pointer to know where the enclosing scope is, no matter how deep the enclosing scope is, no matter how deep the direct recursion has gone.direct recursion has gone.

It is called static, because it is used to It is called static, because it is used to implement the static scope rules of a language implement the static scope rules of a language like Pascal, or C.like Pascal, or C.

Page 31: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 31

So after the second call to Fact, the stack (with So after the second call to Fact, the stack (with the s.c.p’s drawn in would look like this:the s.c.p’s drawn in would look like this:

Page 32: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 32

Now to access a variable one level down in the Now to access a variable one level down in the Symbol Table Stack, we go down one level of Symbol Table Stack, we go down one level of the s.c.p.the s.c.p.

So, in general, accessing a nonlocal variable is So, in general, accessing a nonlocal variable is simple. We know the nesting level at compile simple. We know the nesting level at compile time; that gives us the number of links in the time; that gives us the number of links in the chain. chain.

From this we can see that each variable can be From this we can see that each variable can be identified as two numbers:identified as two numbers:

how many links in the static chain are needed to how many links in the static chain are needed to take us to the correct activation record,take us to the correct activation record,

and how far up from the start of that activation the and how far up from the start of that activation the desired variable is.desired variable is.

Page 33: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 33

There are a couple of ways the static chain There are a couple of ways the static chain pointer can be set.pointer can be set.

When a function calls another, it can copy the base When a function calls another, it can copy the base of its own activation record into the s.c.p of the of its own activation record into the s.c.p of the function it calls.function it calls.

• This happens if a sub-scope is entered.This happens if a sub-scope is entered. If the function called has the same scope as the one If the function called has the same scope as the one

being called, the s.c.p is just copied.being called, the s.c.p is just copied. In our language, where you can have functions In our language, where you can have functions

inside of functions, you can have function A call inside of functions, you can have function A call function B, where B is at a lower level of scope.function B, where B is at a lower level of scope.

• In this case, you have to go find the right s.c.p. by going In this case, you have to go find the right s.c.p. by going back through the s.c.p. chain and copying the right one in.back through the s.c.p. chain and copying the right one in.

• You do this by checking how many ST stack levels you You do this by checking how many ST stack levels you went through to find the name of the function.went through to find the name of the function.

Page 34: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 34

Page 35: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 35

The Display.The Display. Most programs have only a modest number of Most programs have only a modest number of

levels of nesting, and traversing the chain of levels of nesting, and traversing the chain of pointers is not excessively time consuming. pointers is not excessively time consuming.

But there is a faster way to access nonlocal But there is a faster way to access nonlocal variables.variables.

We can have an array of pointer to activation We can have an array of pointer to activation records as shown on the next slide.records as shown on the next slide.

Such an array is called a Such an array is called a displaydisplay..

Page 36: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 36

Page 37: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 37

The display offers quicker access to activation The display offers quicker access to activation records because we require only a change of records because we require only a change of subscript to find the right activation pointer.subscript to find the right activation pointer.

We have shown the display as a separate array We have shown the display as a separate array here, but it could be included as a part of the here, but it could be included as a part of the activation record.activation record.

Notice that we need as many pointers as levels Notice that we need as many pointers as levels of nesting, and each pointer is aimed at the of nesting, and each pointer is aimed at the most recent activation of that levelmost recent activation of that level

The question is, how many levels of nesting are The question is, how many levels of nesting are there?there?

When do you know that number?When do you know that number?

Page 38: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 38

So, when there is a call to someone at the same So, when there is a call to someone at the same level (recursion for example) the old pointer level (recursion for example) the old pointer needs to be saved, and the new pointer placed needs to be saved, and the new pointer placed in the display.in the display.

Page 39: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 39

The creation of a new activation record is a The creation of a new activation record is a shared responsibility.shared responsibility. The calling program will push the things it The calling program will push the things it

knows about onto the stackknows about onto the stack parameters,parameters, chain pointer, chain pointer, return addressreturn address

The subprogram, knowing how many local The subprogram, knowing how many local variables it requires, will take care of the rest.variables it requires, will take care of the rest.

Page 40: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 40

When translating the called subprogram, When translating the called subprogram, the compiler generates code for accessing local the compiler generates code for accessing local

variables via references to the stack, variables via references to the stack, and it must generate special code for each and it must generate special code for each

access to a nonlocal variable, access to a nonlocal variable, either by traversing the chain pointers, either by traversing the chain pointers, or by consulting the display.or by consulting the display.

Page 41: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 41

2.3 Dynamic Memory Management: Run-Time Allocation Procedures like Procedures like newnew or or mallocmalloc allocate a allocate a

block of memory and return a pointer to the block of memory and return a pointer to the block.block.

We must now consider where this memory We must now consider where this memory comes from and how the allocation (and the comes from and how the allocation (and the de-allocation) are managed.de-allocation) are managed.

Page 42: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 42

The blocks come from an area of unused The blocks come from an area of unused memory known as the memory known as the heapheap..

The size of the heap depends upon the amount The size of the heap depends upon the amount of available memory, the size of the program of available memory, the size of the program and its static data.and its static data.

In many cases, all unused memory is shared In many cases, all unused memory is shared between the heap and the stack. between the heap and the stack. The stack grows downward from the top,The stack grows downward from the top, and the heap grows upward from the bottom.and the heap grows upward from the bottom.

If memory demands are so great that we run If memory demands are so great that we run out of space, we get a out of space, we get a heap-stack collisionheap-stack collision and and the program crashes. the program crashes.

Page 43: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 43

The run-time support software has access to The run-time support software has access to the heap and has information about what parts the heap and has information about what parts of it are in use and what parts are available.of it are in use and what parts are available.

When a request for memory comes, it must When a request for memory comes, it must somehow specify the amount of memory somehow specify the amount of memory required.required.

There are a number of ways of managing the There are a number of ways of managing the heap, and over the next few slides we will heap, and over the next few slides we will discuss one of them.discuss one of them.

Page 44: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 44

Initially, the entire Initially, the entire heap is freeheap is free

As blocks are As blocks are requested, they are requested, they are allocated allocated sequentially starting sequentially starting from the bottom of from the bottom of the heap; a heap the heap; a heap pointer marks the pointer marks the boundary between boundary between the blocks that are in the blocks that are in use (active blocks) use (active blocks) and the free area.and the free area.

Page 45: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 45

Eventually, the heap Eventually, the heap pointer may reach the pointer may reach the top of the heap (or top of the heap (or the bottom of the the bottom of the stack). stack).

If no blocks have If no blocks have been freed by this been freed by this time, we are dead; time, we are dead; but this rarely but this rarely happens. Instead, we happens. Instead, we have a picture like have a picture like this: this:

Page 46: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 46

There is now free space scattered in little There is now free space scattered in little chunks through the heap; this situation is chunks through the heap; this situation is called called fragmentationfragmentation..

If we are to make use of this free space that is If we are to make use of this free space that is available, we must know where it is. available, we must know where it is.

The most common way to keep track of free The most common way to keep track of free blocks is to form them into a linked list known blocks is to form them into a linked list known as the as the free-space listfree-space list..

Page 47: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 47

A small amount of A small amount of space is borrowed space is borrowed from each free block from each free block and used to hold its and used to hold its size and a pointer to size and a pointer to the next free block.the next free block.

Page 48: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 48

We continue allocating blocks from the free-We continue allocating blocks from the free-space list.space list.

Searching for a big enough block takes a Searching for a big enough block takes a number of forms; two of the more common number of forms; two of the more common areare first fitfirst fit -- select the first block it finds that is big -- select the first block it finds that is big

enough.enough. best fitbest fit -- traverse the entire free list and pick -- traverse the entire free list and pick

the smallest block that is just big enough.the smallest block that is just big enough. This saves large blocks for large requestsThis saves large blocks for large requests But it can lead to lots of slivers of free memory and But it can lead to lots of slivers of free memory and

therefore to extreme fragmentation.therefore to extreme fragmentation.

Page 49: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 49

The general solution The general solution to the fragmentation to the fragmentation problem is a procedure problem is a procedure known as known as compactioncompaction..

This is a laborious This is a laborious undertaking that slides undertaking that slides all the blocks that are all the blocks that are in use down to the in use down to the bottom of the heap so bottom of the heap so that the free space that the free space moves up to the top moves up to the top and forms one big and forms one big block again.block again.

Page 50: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 50

There are four basic steps for this algorithm:There are four basic steps for this algorithm: Finding the pointers Finding the pointers

This is the hard job.This is the hard job. make a list of all the pointers in the user’s program.make a list of all the pointers in the user’s program.

Dress rehearsal Dress rehearsal don’t actually move the blocks, but figure out where don’t actually move the blocks, but figure out where

to move themto move them

Pointer UpdatingPointer Updating Use the list you found in step 1, and update pointers Use the list you found in step 1, and update pointers

with their new value.with their new value.

Moving.Moving. Now that pointers are correct, move the blocks.Now that pointers are correct, move the blocks.

Page 51: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 51

Garbage and Dangling References.Garbage and Dangling References. If a programmer loses the only pointer to an If a programmer loses the only pointer to an

allocated block of memory, that block is termed allocated block of memory, that block is termed garbagegarbage..

There are a few ways in which the system can There are a few ways in which the system can help the programmer avoid the creation of help the programmer avoid the creation of garbage.garbage.

One method is to provide each block with a One method is to provide each block with a reference count (the number of pointers pointing to reference count (the number of pointers pointing to the block)the block)

• It is invisible to the programmerIt is invisible to the programmer

• It is managed by code inserted into pointer assignments by It is managed by code inserted into pointer assignments by the compiler.the compiler.

Page 52: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 52

If the count ever goes to zero, the block is If the count ever goes to zero, the block is returned to the free-space list, whether the user returned to the free-space list, whether the user disposeddisposed of it or not. of it or not.

This works most of the time, but not always.This works most of the time, but not always.

Page 53: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 53

Garbage Collection.Garbage Collection. Some languages, most notably LISP, provide Some languages, most notably LISP, provide

no explicit disposal mechanism, and hence no no explicit disposal mechanism, and hence no opportunity to create dangling references.opportunity to create dangling references.

You are free to create garbage with wild You are free to create garbage with wild abandon, and at intervals the support system abandon, and at intervals the support system cleans up your mess for you.cleans up your mess for you.

This process is known as This process is known as garbage collectiongarbage collection.. Garbage collection achieves the seemingly Garbage collection achieves the seemingly

impossible: it locates garbage (which we impossible: it locates garbage (which we though was by definition impossible to locate) though was by definition impossible to locate) and returns it to the free-space list.and returns it to the free-space list.

Page 54: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 54

The trick is that we don’t locate the set of all The trick is that we don’t locate the set of all garbage; we locate its complement.garbage; we locate its complement.

Here is the basic procedure:Here is the basic procedure: Go sequentially through the heap and unmark every Go sequentially through the heap and unmark every

block.block. Starting with all the pointers in the user’s code, Starting with all the pointers in the user’s code,

follow the chains of pointers and mark all the blocks follow the chains of pointers and mark all the blocks encountered. (At this point we have marked encountered. (At this point we have marked everything that everything that isn’tisn’t garbage) garbage)

Now go sequentially through the heap again and Now go sequentially through the heap again and identify all unmarked blocks and return them to the identify all unmarked blocks and return them to the free-space list.free-space list.

Page 55: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 55

It should be obvious that while garbage It should be obvious that while garbage collection (or compaction) is going on, the collection (or compaction) is going on, the execution of the user’s program must be execution of the user’s program must be suspended.suspended.

Hence you may wish to provide for some Hence you may wish to provide for some notification that garbage collection is going on.notification that garbage collection is going on.

Otherwise when the program stops running, Otherwise when the program stops running, the user may suspect a bug, and panic.the user may suspect a bug, and panic.

Page 56: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 56

3. Summary The topics discussed in this chapter are the The topics discussed in this chapter are the

basics of memory management at compile time basics of memory management at compile time and at run time.and at run time.

Some languages may create special problems:Some languages may create special problems: unlabeled and labeled unlabeled and labeled COMMONCOMMON blocks in blocks in FORTRANFORTRAN require some special handling. require some special handling.

Languages like Languages like PL/IPL/I, in which subprograms are , in which subprograms are separately compiled, require that the calling separately compiled, require that the calling program have enough information to create program have enough information to create activation records properly.activation records properly.

Page 57: Chapter 8 Memory Use. Chapter 8 -- Memory Use2  In this chapter we will consider memory use during compilation and run time.  During compilation, the

Chapter 8 -- Memory Use 57

Garbage collection and compaction are not Garbage collection and compaction are not always available.always available. Garbage collection is normally associated with Garbage collection is normally associated with

languages in which there is no explicit de-languages in which there is no explicit de-allocation of variables.allocation of variables.

Many languages do the best they can with the Many languages do the best they can with the heap, and if you run out of space because of heap, and if you run out of space because of fragmentation, you’re dead.fragmentation, you’re dead.