Terminology Terminology (contd.) Exception : An error, or more generally, an Resumption model : After the execution unusual condition. of the handler, control returns back to the Raise , Throw , Signal : A statement is said to statement that raised the exception. "raise" (or "throw" or "signal") an exception if th e Example: signal handling in UNIX/C. execution of this statement leads to an exception. • ("throw" is the term used in C++/Java language Termination Model : C ontrol does not descriptions, "raise" is used in SML.) return to that statement after the handler is Catch : A catch statement is used in C++/Java to executed. declare a handler. The keyword "handle" is used • Example: Exception handling in most in SML to denote the same concept . programming languages (C++, Java and SML) .
CSE 307 Spring 2004 1 CSE 307 Spring 2004 2 R. Sekar R. Sekar
Exception Handling Exception Handling in C++/Java
Uncaught exceptions are propagated up the call stack. Syntax:
CSE 307 Spring 2004 3 CSE 307 Spring 2004 4 R. Sekar R. Sekar
Exception Handling in C++/Java(contd.) Exception Vs Return Codes Example: Exceptions are often used to communicate error valu es int fac(int n) { from a callee to its caller. Return values provide alternate if (n <= 0) throw (-1) ; else if (n > 15) throw ("n too large"); means of communicating errors. else return n*fac(n-1); } void g (int n) { int k; Example use of exception handler : try { k = fac (n) ;} float g (int a, int b, int c) { catch (int i) { cout << "negative value invalid" ; } float x = 1./fac(a) + 1./fac(b) + 1./fac(c) ; r eturn x ; } catch (char *s) { cout << s; } main() { catch (...) { cout << "unknown exception" ;} try { g(-1, 3, 25); } catch (char *s) { cout << "Exception `" << s << "'raised, exi ting\n"; } catch (...) { cout << "Unknown exception, eixting\n"; } use of g (-1) will print "negative value invalid" g (16) will print "n too large" If an unexpected error were to arise in evaluation of fac or g, such as We do not need to concern ourselves with every running out of memory, then "unknown excpetion“ will be printed point in the program where an error may arise.
CSE 307 Spring 2004 5 CSE 307 Spring 2004 6 R. Sekar R. Sekar
Exception Vs Return Codes(contd.) Use of Exceptions in C++ Vs Java
float g(int a, int b, int c) { int x1 = fac(a) ; If return codes In C++, exception handling was an after-thought. if (x1 > 0) { were used to • Earlier versions of C++ did not support exception int x2 = fac(b) ; indicate errors, handling. if (x2 > 0) { int x3 = fac(c) ; then we are • Exception handling not used in standard libraries if (x3 > 0) { forced to check • Net result: continued use of return codes for error- return 1./x1 + 1./x2 + 1./x3 ; checking } return codes } (and take In Java, exceptions were included from the } beginning. return …; // there was an error appropriate All standard libraries communicate errors via exceptions. } action) at every • main() { • Net result: all Java programs use exception handling int x = g(-1, 2, 25); point in code . model for error-checking, as opposed to using return if (x < 0) { /* identify where error codes. occurred, print */ } CSE 307 Spring 2004 7 CSE 307 Spring 2004 8 R. Sekar R. Sekar
Implementation of Exception Handling in Programming Languages Heap management Exception handling can be implemented by Issues adding "markers" to ARs to indicate the points in program where exception handlers are available. • No LIFO property, so management is difficult Entering a try-block at runtime would cause such • Fragmentation a marker to be put on the stack • Locality When exception arises, the RTE gets control and Models searches down from stack top for a marker. • Explicit allocation and free (C, C++) Exception then "handed" to the catch statement • Explicit allocation, automatic free (Java) of this try-block that matches the exception • Automatic allocation and free (SML, Python, If no matching catch statement is present, search Javascript) for a marker is contined further down the stack
CSE 307 Spring 2004 9 CSE 307 Spring 2004 10 R. Sekar R. Sekar
Fragmentation Reducing Fragmentation
Internal fragmentation Use blocks of single size (early LISP) • When asked for x bytes, allocator returns y > x • Limits data-structures to use less efficient implementations. bytes; y-x represents internal fragmentation Use bins of fixed sizes, e.g., 2 n for n=0,1,2,... External fragmentation • When you run out of blocks of a certain size, break up ablock of next available size When (small) free blocks of memory occur in • • Eliminates external fragmentation, but increases internal between used blocks fragmentation the memory manager may have a total >> N bytes of free • Maintain bins as LIFO lists to increase locality memory available, but none may be large enough to satisfy a request of size N. malloc implementations (Doug Lea) • For small blocks, use bins of size 8k bytes, 0 < k < 64 • For larger blocks, use bins of sizes 2 n for n > 9
CSE 307 Spring 2004 11 CSE 307 Spring 2004 12 R. Sekar R. Sekar
Coalescing Explicit Vs Implicit Management
What if a program allocates many 8 byte chunks,free s Explicit memory management can be more them all and then requests lots of 16 byte chunks? efficient, but takes a lot of programmer effort Need to coalesce 8-byte chunks into 16-byte chunks • Programmers often ignore memory management • Requires additional information to be maintained early in coding, and try to add it later on for allocated blocks: where does the current block end, • But this is very hard, if not impossible and whether the next block is free • Result: • Majority of bugs in production code is due to memory management errors • Memory leaks • Null pointer or uninitalized pointer access • Access through dangling pointers
CSE 307 Spring 2004 13 CSE 307 Spring 2004 14 R. Sekar R. Sekar
Managing Manual Deallocation Garbage Collection
How to avoid errors due to manual deallocation Garbage collection aims to avoid problems of memory associated with manual deallocation • Never free memory!!! • Identify and collect garbage automatically Use a convention of object ownership (owner • What is garbage? responsible for freeing objects) Unreachable memory • Tends to reduce errors, but still requires a careful design from • the beginning. (Cannot ignore memory deallocation concerns Automatic garbage collection techniques initially and add it later.) have been developed over a long time • Smart data structures, e.g., reference counting objects • Since the days of LISP (1960s) • Region-based allocation • When a bunch of objects having equal life time are allocated
CSE 307 Spring 2004 15 CSE 307 Spring 2004 16 R. Sekar R. Sekar
Garbage Collection Techniques Reference Counting Reference Counting Each heap block maintains a count of the • Works if there are no cyclic structures number of pointers referencing it. Mark-and-sweep Each pointer assignment Generational collectors increments/decrements this count Issues Deallocation of a pointer variable decrements • Overhead (memory and space) this count • Pause-time When reference count becomes zero, the • Locality block can be freed
CSE 307 Spring 2004 17 CSE 307 Spring 2004 18 R. Sekar R. Sekar
Reference Counting Mark-and-Sweep (“Trace-based”)
Disadvantages Mark every allocated heap block as • Does not work with cyclic structures “unreachable” • May impact locality Start from registers, local and global • Increases cost of each pointer update operation variables Advantages Do a DFS, following the pointers • Overhead is predictable, fixed • Mark each heap block visited as “reachable” Garbage is collected immediately, so more • efficient use of space At the end of the sweep phase, reclaim all heap blocks still marked as unreachable
CSE 307 Spring 2004 19 CSE 307 Spring 2004 20 R. Sekar R. Sekar
Issues with GC Copying Collection Memory fragmentation Instead of doing a sweep, simply copy over • Memory pages may become sparsely populated all reachable heap blocks into a new area • Performance will be hit due to excessive virtual After the copying phase, all original blocks memory usage and page faults can be freed Can be a problem with explicit memory • management as well Now, memory is compacted, so paging performance will be much better Solution: Needs up to twice the memory of compacting • Compacting GC • Copy live structures so that they are contiguous collector, but can be much faster • Copying GC • Reachable memory is often a small fraction of total memory CSE 307 Spring 2004 21 CSE 307 Spring 2004 22 R. Sekar R. Sekar
Generational GC Garbage collection in Java
Take advantage of the fact that most objects Generational GC for young objects are short-lived “Tenured” objects stored in a second region Exploit this fact to perform GC faster • Use mark-and-sweep with compacting Idea: Makes use of multiple processors if available • Divide heap into generations References If all references go from younger to older generation • http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html (as most do), can collect youngest generation w/o • scanning regions occupied by other generations • http://www.ibm.com/developerworks/java/library/j-jtp11253/ • Need to track references from older to younger generation to make this work in all cases
CSE 307 Spring 2004 23 CSE 307 Spring 2004 24 R. Sekar R. Sekar
GC for C/C++
Cannot distinguish between pointers and nonpointers • Need “conservative garbage collection” The idea: if something “looks” like a pointer, assu me that it may be one! • Problem: works for finding reachable objects, but cannot modify a value without being sure • Copying and compaction are ruled out! Reasonable GC implementations are available, but they do have some drawbacks • Unpredictable performance • Can break some programs that modify pointer values before storing them in memory
CSE 307 Spring 2004 25 R. Sekar