05a_MemoryManagement.ppt

653 views
620 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
653
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

05a_MemoryManagement.ppt

  1. 1. Memory Management How memory is used to hold data used by processes.
  2. 2. Memory Issues <ul><li>How is memory organized? </li></ul><ul><li>How are different parts of the program stored in memory? </li></ul><ul><li>Where is data stored in memory? </li></ul><ul><li>When is memory allocated to variables? code? </li></ul><ul><li>When is memory freed? </li></ul><ul><li>How can the programmer specify memory sizes? </li></ul><ul><li>How can the programmer examine memory? </li></ul>
  3. 3. Memory Hierarchy <ul><li>registers </li></ul><ul><li>cache: L1 cache and L2 cache </li></ul><ul><li>RAM - main memory </li></ul><ul><li>Secondary storage: hard disk or flash memory </li></ul><ul><li>Tertiary storage: </li></ul><ul><ul><li>tape - 4mm (DAT), 8mm, Digital Linear Tape </li></ul></ul><ul><ul><li>DVD or CD -ROM or -RW </li></ul></ul>
  4. 4. Memory for Program Execution <ul><li>To run a program, the operating system allocates at least two memory segments for the process: </li></ul><ul><li>“ text segment ” containing the machine instructions for the program. </li></ul><ul><ul><li>this segment is usually read-only and can be shared my multiple processes running the same program </li></ul></ul><ul><li>&quot; data segment &quot; to hold values used by a process. </li></ul><ul><ul><li>includes variables, constants, unnamed values, and data required to run process, such as saved registers and references to environments </li></ul></ul><ul><ul><li>each process requires its own data segment </li></ul></ul><ul><li>the data segment is the area most interesting to the programmer. </li></ul>
  5. 5. Three parts of a runtime environment <ul><li>The data segment may be divided into 3 parts: </li></ul><ul><li>Static area for values that exist during entire duration of the process. </li></ul><ul><ul><li>global and static variables, load-time constants. </li></ul></ul><ul><ul><li>size is fixed and known before program starts execution </li></ul></ul><ul><li>Stack area for run-time data whose lifetime obeys last-in first-out discipline. </li></ul><ul><ul><li>arguments and local variables in subroutines. </li></ul></ul><ul><li>Heap area for data allocated dynamically. </li></ul><ul><ul><li>lifetime doesn't follow LIFO rule </li></ul></ul><ul><ul><li>size may not be not known at compile/load time </li></ul></ul><ul><ul><li>objects in Java, C &quot;malloc&quot; storage, C++ &quot;new&quot; allocations </li></ul></ul>
  6. 6. Memory Layout of Data Segment HEAP (size can grow) STATIC AREA (size fixed) STACK (size can grow) (unallocated memory) The three memory areas have distinct purposes. The size of the Static Area is known after program is linked; it doesn't grow dynamically. The Stack and Heap can grow/shrink dynamically. Therefore, the operating environment usually arranges them to &quot;grow&quot; towards unallocated space .
  7. 7. Where are the variables? <ul><li>In what memory area are these variables allocated? </li></ul><ul><li>When is storage allocated and freed? </li></ul>int count = 0; int sumdata( ) { long sum ; int value ; do { scanf(&quot;%d&quot;, &value); sum = sum + value; count++; } while (value != 0); return sum; } int main( ) { long sum ; double average ; sum = sumdata(); average = sum / count; printf( &quot;average is %f&quot;, average ); } Q: Find at least 3 bugs in this code
  8. 8. Memory Usage HEAP (size can grow) count sum average [temporaries] [return addr and value] sum value (unallocated memory) STATIC AREA stack space for &quot;main&quot; stack space for &quot;sumdata&quot;
  9. 9. Where are the variables? <ul><li>In what memory area are these variables allocated? </li></ul><ul><li>When is storage allocated and freed? </li></ul>#define MAXSIZE 1000 extern double size ; double* getarray(int n ) { // pointer to array double *a ; // allocate storage a = (double *) malloc( n*sizeof(double) ) ; ... read data into a ... return a; } int main( ) { double * arr ; double sum ; arr = getarray(size); for(int k =0; k<size; k++) sum += arr[k]; }
  10. 10. Memory Usage 1000*sizeof(double) size (allocated by another part of the program) arr sum k n [return addr and value] a (unallocated memory) STATIC AREA stack space for &quot;main&quot; stack space for &quot;getarray&quot; HEAP *a value points to
  11. 11. Where's the memory (1)? <ul><li>What is wrong with this C program? </li></ul><ul><li>Where is the storage used by each value? </li></ul>/* print a prompt and get reply as a string */ char *getreply( ) { char *reply; printf(&quot; What's your name? &quot;); scanf(&quot; %s &quot;, reply); printf(&quot; Hello, %s &quot;, name); return reply; } int main( ) { char *name = getreply(); }
  12. 12. Where's the memory (2)? <ul><li>Fix it by allocating local storage for reply string. </li></ul><ul><li>Q: When is the storage for *reply allocated? when freed? </li></ul>/* print a prompt and get reply as a string */ char *getreply( ) { char reply[20]; // can hold string of 19 chars printf(&quot; What's your name? &quot;); scanf(&quot; %s &quot;, reply); printf(&quot; Hello, %s &quot;, name); return reply; } int main( ) { char *name = getreply(); printf(&quot; Goodbye, %s &quot;, name); }
  13. 13. Where's the memory (2)? <ul><li>Previous example works on some OS. </li></ul><ul><li>What if you call getreply more than once? </li></ul>int main( ) { char *name1 = getreply(); printf(&quot; Goodbye, %s &quot;, name1); char *name2 = getreply(); printf(&quot; Goodbye, %s &quot;, name2); printf(&quot; Sayonara, %s and %s &quot;, name1, name2); }
  14. 14. Where's the memory (3)? <ul><li>Fix it by allocating dynamic storage for reply string. </li></ul><ul><li>Q: When is the storage for *reply allocated? when freed? </li></ul>/* print a prompt and get reply as a string */ char *getreply( ) { char reply = (char *) malloc( 20 ); printf(&quot; What's your name? &quot;); scanf(&quot; %s &quot;, reply); printf(&quot; Hello, %s &quot;, name); return reply; } int main( ) { char *name = getreply(); printf(&quot; Goodbye, %s &quot;, name); }
  15. 16. Where's the memory (Java)? <ul><li>Where would you expect the memory for these variables to be allocated? </li></ul><ul><li>When is the memory allocated? When is it freed? </li></ul>public class Greeter { String who = &quot;nerd&quot;; public void greet( ) { int n = 100; System.out .printf( &quot;hello, %s&quot;, who ); } public static int main( ... ) { Greeter g = new Greeter(); g.greet( ); } } Where is System.out ?
  16. 17. Languages and Environments <ul><li>Languages differ in how they allocate storage for data: </li></ul><ul><li>Static allocation : older Fortran compilers allocate everything statically -- including subroutine activations records. </li></ul><ul><li>Heap-oriented : interpreted languages where the data type and size of data is determined at runtime -- put everything on the heap. Scheme, ML (functional) and Smalltalk (O-O). The interpreter itself may use static and stack storage. </li></ul><ul><li>Multiple areas : most common for compiled languages. </li></ul>
  17. 18. The Runtime Stack <ul><li>Used for: </li></ul><ul><ul><li>Procedure/function/method calls </li></ul></ul><ul><ul><li>temporaries </li></ul></ul><ul><ul><li>local variables </li></ul></ul><ul><li>Temporaries: intermediate results that cannot be kept in registers. </li></ul><ul><li>Procedure calls: Sebesta, Chapter 8. </li></ul><ul><li>Local variables: part of calls, but can be considered independently, showing LIFO behavior for nested scopes (next slide). </li></ul>
  18. 19. Example of stack allocation in C Local variables Locals & Temps Locals & Temps Locals & Temps main sub1 sub2 sub3 int sub3 ( int a ) { do something; } float sub2 ( int x, int y ) { result = sub3(x) + sub3(y); return result; } int sub1 ( int u, int v ) { int b = 2; float z = sub2(b,u) + sub2(b,v); } int main ( ) { sub1( 10, 20 ); Return address Parameters Return address Parameters Return address Parameters
  19. 20. Heap Allocation <ul><li>Used for dynamic allocation of storage. </li></ul><ul><li>In statically typed languages like C, C++, and Java the heap is used for objects allocated using &quot;new&quot;, &quot;malloc&quot;, etc. </li></ul><ul><ul><li>in C/C++ this can include any data type, e.g. int *p = new int; </li></ul></ul><ul><ul><li>in Java, heap is used for reference types (&quot;objects&quot;) only; all objects are allocated on the heap. </li></ul></ul><ul><ul><li>this includes arrays in Java (any array is an object). </li></ul></ul><ul><li>Dynamically typed languages such as LISP, SmallTalk, Perl, use the heap for almost all data. </li></ul><ul><ul><li>the type or size of data stored in a variable can change at run-time. </li></ul></ul><ul><ul><li>heap allocation is done automatically (no special syntax such as &quot;new&quot; or &quot;malloc&quot; required) </li></ul></ul>
  20. 21. Heap Example 1 <ul><li>Scanner input = </li></ul><ul><li>new Scanner( System.in ); </li></ul><ul><li>String result = &quot;&quot;; </li></ul><ul><li>while( input.hasNext( ) ) { </li></ul><ul><li>String word = input.next( ); </li></ul><ul><li>result = result + &quot; &quot; + word; </li></ul><ul><li>} </li></ul>Input: this is why String processing is so slow free HEAP: FL
  21. 22. Heap Example 1 <ul><li>Scanner input = </li></ul><ul><li>new Scanner( System.in ); </li></ul><ul><li>String result = &quot;&quot;; </li></ul><ul><li>while( input.hasNext( ) ) { </li></ul><ul><li>String word = input.next( ); </li></ul><ul><li>result = result + &quot; &quot; + word; </li></ul><ul><li>} </li></ul>this is why this is why String this is why Str ing HEAP: Input: this is why String processing is so slow FL word 1 result 0 &quot;&quot; word 2 result 1 this word 3 result 2 this is result 3 word 4 result 4
  22. 23. Heap Example 1 <ul><li>Scanner input = </li></ul><ul><li>new Scanner( System.in ); </li></ul><ul><li>String result = &quot;&quot;; </li></ul><ul><li>while( input.hasNext( ) ) { </li></ul><ul><li>String word = input.next( ); </li></ul><ul><li>result = result + &quot; &quot; + word; </li></ul><ul><li>} </li></ul>this &quot;&quot; is this why this is this is why String this is why Str ing HEAP: After 4 iterations, the first four values of result and word no longer longer referenced. They are &quot;garbage&quot;. FL word 4 result 4
  23. 24. Heap Example 2 <ul><li>Scanner input = new Scanner( in ); </li></ul><ul><li>String [ ] r = new String[10]; </li></ul><ul><li>while( input.hasNext( ) && k < 10 ) { </li></ul><ul><li>String word = input.next( ); </li></ul><ul><li>r[k] = word; </li></ul><ul><li>} </li></ul>Input: this is why String processing is so slow free HEAP: FL r [S
  24. 25. Heap Example 2 <ul><li>Scanner input = new Scanner( in ); </li></ul><ul><li>String [ ] r = new String[10]; </li></ul><ul><li>while( input.hasNext( ) && k < 10 ) { </li></ul><ul><li>String word = input.next( ); </li></ul><ul><li>r[k] = word; </li></ul><ul><li>} </li></ul>this r [S why r[1] is r[3] r[2] String proces.. HEAP: Input: this is why String processing is so slow FL r[0] word r[4]
  25. 26. Heap Management <ul><li>Heap management involves: </li></ul><ul><li>allocating new blocks to satisfy memory requests </li></ul><ul><ul><li>must find a suitable free block </li></ul></ul><ul><li>maintain a list of unused (&quot;free&quot;) blocks </li></ul><ul><ul><li>may be many free blocks spread over the heap </li></ul></ul><ul><ul><li>the free blocks themselves may be used to create a linked list. </li></ul></ul><ul><li>cope with fragmentation of free heap space </li></ul>
  26. 27. Management of Heap Example 1 <ul><li>When the programmer (or garbage collector) reclaims the unused blocks, they are added to the free list. </li></ul><ul><li>the heap manager combines free space into larger blocks. </li></ul><ul><ul><li>combining free blocks is not as easy as it looks here -- what if blocks are returned at different times? </li></ul></ul><ul><li>the old contents of the blocks usually are not cleared (can be a security issue) </li></ul>&quot;&quot; this this is this is why this is why String this is why Str ing HEAP: FL word 4 result 4
  27. 28. Management of Heap <ul><li>typically, the heap becomes fragmented after extended use </li></ul><ul><li>no good solution to this </li></ul><ul><li>some heap managers copy (move) blocks to combine free space </li></ul><ul><ul><li>this has a lot of overhead </li></ul></ul><ul><ul><li>must also change references to moved blocks in running processes! </li></ul></ul>this [S junk this morejunk is why xxxxxx String HEAP:
  28. 29. Heap Management in C <ul><li>Allocate storage: void *malloc( size ) </li></ul><ul><li>// array of int </li></ul><ul><li>int *array = (int *) malloc ( 20*sizeof(int) ); </li></ul><ul><li>for(k = 0; k<20; k++) array[k] = ...; </li></ul><ul><li>// character string of length 80 </li></ul><ul><li>char *s = (char *) malloc ( 80*sizeof(char) ); </li></ul><ul><li>Free storage: void free( void* ptr ) </li></ul><ul><li>&quot;free&quot; requires a pointer argument </li></ul><ul><li>free( array ); </li></ul><ul><li>free( s ); </li></ul>
  29. 30. Heap Management in C++ <ul><li>Allocate storage: new </li></ul><ul><li>// a single double (sort of useless) </li></ul><ul><li>double *d = new double(3.14159); </li></ul><ul><li>// array of int </li></ul><ul><li>int *array = new int[100]; </li></ul><ul><li>// character string of length 80 </li></ul><ul><li>char *s = new char[80]; </li></ul><ul><li>Free storage: delete reference </li></ul><ul><li>delete d; // free a scalar variable </li></ul><ul><li>delete [ ] array; </li></ul>
  30. 31. Safe Programming <ul><li>Test whether memory allocating succeeded before continuing. </li></ul>// C int *array = (int *)malloc( 100*sizeof(int) ); if ( ! array ) fprintf( stderr, &quot; malloc failed &quot;); // C++ int *array = new int[100]; if ( array == NULL ) cerr << &quot; new failed &quot;;
  31. 32. Garbage <ul><li>the above solution can lead to creation of garbage... </li></ul>char *getreply( char *prompt ) { char *reply; reply = (char *)malloc(80); /* allocate storage */ printf(&quot;%s&quot;, prompt); scanf(&quot;%s&quot;, reply); return reply; } int main( ) { char *s; s = getreply(&quot;Want a million baht?&quot;); if ( strcmp(s,&quot;yes&quot;)==0 ) PlayLottery( ); s = getreply(&quot;Want to study more?&quot;); // answer to the first question is now garbage // C programs must explicitly &quot;free&quot; dynamic storage
  32. 33. Garbage Collection <ul><li>Automatic recycling of dynamic storage allocations no longer in use by program. </li></ul><ul><li>Pioneered by LISP, later by SmallTalk </li></ul><ul><ul><li>in LISP, programmer doesn't explicitly request storage, so why require him to free storage? </li></ul></ul><ul><ul><li>same idea in SmallTalk: make objects easy </li></ul></ul><ul><li>How does heap manager know when a block of allocated storage is no longer in use? </li></ul>
  33. 34. Garbage Collection Techniques <ul><li>Reference counting </li></ul><ul><ul><li>in each object, keep a counter of how many objects reference it </li></ul></ul><ul><ul><li>doesn't work! (example: circular queue) </li></ul></ul><ul><ul><li>expensive: uses space in objects and time to update the counts </li></ul></ul><ul><li>Mark and Sweep </li></ul><ul><ul><li>OK, but still requires some space and time </li></ul></ul><ul><li>Other Techniques </li></ul><ul><ul><li>dividing heap into halves, swap halves to clean up </li></ul></ul><ul><ul><li>use age of objects (&quot;most objects die young&quot;) </li></ul></ul>
  34. 35. Avoiding Fragmentation <ul><li>Maintain free lists of &quot;standard&quot; block sizes </li></ul><ul><li>Combine/break blocks as needed </li></ul><ul><li>used by algorithm called the &quot; buddy system &quot; </li></ul><ul><li>Example: </li></ul><ul><ul><li>create separate free lists of block sizes 32, 64, 128, ... </li></ul></ul><ul><ul><li>FL1 -> list of 32B blocks </li></ul></ul><ul><ul><li>FL2 -> list of 64B blocks </li></ul></ul><ul><ul><li>FL3 -> list of 128B blocks, etc. </li></ul></ul><ul><ul><li>if an application needs a block of size (say) 60 bytes and there is nothing in FL2, then split a 128B block into 2 64B blocks. </li></ul></ul><ul><ul><li>if the manager frees two adjacent 64B blocks, it can combine them into one 128B (FL3) block </li></ul></ul>
  35. 36. Heap Question <ul><li>Suppose the heap contains only 3 free blocks like this: </li></ul><ul><li>Address Block Size </li></ul><ul><li>0x10FF0 4KB </li></ul><ul><li>0x1BC20 3KB </li></ul><ul><li>0x3C000 4KB </li></ul><ul><li>Your program requests 10KB, like this: </li></ul><ul><li>char *s; </li></ul><ul><li>s = (char *)malloc( 10000 ); </li></ul><ul><li>Q: what does malloc return? (a) 10000 char (combine all 3 blocks), (b) 4096 char (largest block), (c) null </li></ul>
  36. 37. Dangling References and Garbage <ul><li>A dangling reference is a location that has been deallocated from the environment, but is still referenced by the program. </li></ul><ul><li>Garbage is memory that is still allocated to the process but has become inaccessible to the process's program. </li></ul><ul><li>Which is the more serious problem? </li></ul><ul><ul><li>Garbage may cause a program to exhaust memory and fail; but, the computations performed by program are correct (as far as it completed) </li></ul></ul><ul><ul><li>Dangling references can cause program to return incorrect results even though program runs OK. </li></ul></ul>
  37. 38. Dangling References <ul><li>Example in C: invalid reference to local storage </li></ul>/* print a prompt and get a reply from the user */ char *getreply( char *prompt ) { char reply[80]; /* string to hold user's response */ printf(&quot;%s&quot;, prompt); scanf(&quot;%s&quot;, reply); return reply; /* reference to a local variable */ } int main( ) { char *s1, *s2; s1 = getreply(&quot; Want a million baht? &quot;); s2 = getreply(&quot; Want to study more? &quot;); Now s1 and s2 point to local storage on the stack Probably s1 = s2 = response to second question !
  38. 39. Dangling References Fixed <ul><li>To avoid this problem... </li></ul>/* print a prompt and get a reply from the user */ char *getreply( char *prompt ) { char *reply; reply = (char *)malloc(80); /* allocate storage */ printf(&quot;%s&quot;, prompt); scanf(&quot;%s&quot;, reply); return reply; } int main( ) { char *s1, *s2; s1 = getreply(&quot; Want a million baht? &quot;); s2 = getreply(&quot; Want to study more? &quot;); s1 and s2 refer to valid (and distinct) storage locations But, programmer must free s1 and s2 to avoid creating garbage.
  39. 40. Dangling References (2) <ul><li>Alias (pointer) to deallocated storage. Not clear in this small example, but a problem in larger apps. </li></ul>/* create pointers to refer to the strings */ char *s, *result; int k; /* allocate a string of length 255 (bad style) */ s = (char *) malloc( 255*sizeof(char) ); /* read input into the string */ scanf(&quot;%s&quot;, s); result = s; if ( strcmp(result,&quot;yes&quot;) == 0 ) DoSomething( ); /* done with result, so free it! */ free( result ); /* oops! s is a dangling reference */
  40. 41. Solution to Dangling References <ul><li>Don't allow programmer to deallocate storage! </li></ul><ul><li>Don't allow pointers, either. </li></ul><ul><li>Java and C#: use &quot;reference&quot; instead of pointer. references cannot be manipulated like pointers (no p++). </li></ul><ul><li>Why Dynamic Allocation? </li></ul><ul><li>can we eliminate dynamic allocation (other than stack automatic variables)? </li></ul><ul><li>If we don't allow dynamic allocation, many useful programs would not be possible. </li></ul>
  41. 42. Memory Management in Java
  42. 43. Features <ul><li>Memory is managed by the Java Virtual Machine (JVM) </li></ul><ul><ul><li>this ensures that a Java application never accesses memory outside the JVM. </li></ul></ul><ul><ul><li>it also allows the JVM to &quot;catch&quot; memory violations and raise a run-time exception </li></ul></ul><ul><li>JVM provides both heap and stack space to Java app. </li></ul><ul><li>JVM performs automatic garbage collection. </li></ul>
  43. 44. Heap Layout <ul><li>&quot; Most objects die young &quot; -- </li></ul><ul><li>over 90% of all objects are de-referenced </li></ul><ul><li>within the first few iterations of garbage collection. </li></ul><ul><li>This influences Java's heap management strategy </li></ul><ul><li>Divide the heap into 4 sub-areas: </li></ul>Eden Space (newly created objects) Survivor Space (objects that survive first gc) Tenured Generation (objects that survive long enough are promoted to this area) Permanent Generation (tenured objects that survive really long are promoted to here)
  44. 45. References <ul><li>http://www.informit.com/guides/ content.asp?g=java&seqNum=249&rl=1 </li></ul><ul><li>Java Memory Profilers: </li></ul><ul><li>http://www.manageability.org/blog/stuff/open-source-profilers-for-java </li></ul>

×