Lecture 17 Garbage Collection CS 201 j Engineering
Lecture 17: Garbage Collection CS 201 j: Engineering Software University of 2002 Virginia 5 November Computer Science CS 201 J Fall 2002 David Evans http: //www. cs. virginia. edu/evans
Menu • • • Stack and Heap Mark and Sweep Stop and Copy Reference Counting Java’s Garbage Collector 5 November 2002 CS 201 J Fall 2002 2
Stack and Heap Review Heap Stack public class Strings { public static void test () { A String. Buffer sb = new String. Buffer ("hello"); B } static public void main (String args[]) { 1 test (); 2 test (); 3 } } sb java. lang. String. Buffer “hello” When do the stack and heap look like this? 5 November 2002 CS 201 J Fall 2002 3
Stack and Heap Review Stack Heap public class Strings { public static void test () { String. Buffer sb = new String. Buffer ("hello"); B } static public void main (String args[]) { test (); 2 test (); } } 5 November 2002 sb CS 201 J Fall 2002 java. lang. String. Buffer “hello” 4
Garbage Heap Stack Heap public class Strings { public static void test () { String. Buffer sb = new String. Buffer ("hello"); } } static public void main (String args[]) { while (true) test (); } “hello” “hello” “hello” “hello” “hello” “hello” “hello” 5 November 2002 CS 201 J Fall 2002 5
Garbage Collection • System needs to reclaim storage on the heap used by garbage objects • How can it identify garbage objects? • How come we don’t need to garbage collect the stack? 5 November 2002 CS 201 J Fall 2002 6
Mark and Sweep 5 November 2002 CS 201 J Fall 2002 7
Mark and Sweep • John Mc. Carthy, 1960 (first LISP implementation) • Start with a set of root references • Mark every object you can reach from those references • Sweep up the unmarked objects What are the root references? References on the stack. 5 November 2002 CS 201 J Fall 2002 8
public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); … (open file for reading) while (…not end of file…) { Species current = new Species (…name from file…, …genome from file…); ss. insert (current); } } public class Species. Set { private Vector els; public void insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } 5 November 2002 CS 201 J Fall 2002 9
“in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species “Duck” els: “CATAG” ss: Species. Set. insert current: Species name: genome: this: Species. Set “Goat” s: Species Top of Stack “CAGTG” name: genome: public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); while (…not end of file…) { Species current = new Species (…name…, …genome…); ss. insert (current); } } public class Species. Set { private Vector els; 5 void November 2002 public insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 10 “CGATG”
After els. add (s)… “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species “Duck” els: “CATAG” ss: Species. Set. insert current: Species name: genome: this: Species. Set “Goat” s: Species Top of Stack “CAGTG” name: genome: public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); while (…not end of file…) { Species current = new Species (…name…, …genome…); ss. insert (current); } } public class Species. Set { private Vector els; 5 void November 2002 public insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 11 “CGATG”
Species. Set. insert returns… “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species “Duck” els: “CATAG” ss: Species. Set. insert current: Species name: genome: this: Species. Set “Goat” s: Species Top of Stack “CAGTG” name: genome: public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); while (…not end of file…) { Species current = new Species (…name…, …genome…); ss. insert (current); } } public class Species. Set { private Vector els; 5 void November 2002 public insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 12 “CGATG”
Finish while loop… “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species “Duck” els: “CATAG” ss: Species. Set current: Species Top of Stack name: genome: “Goat” “CAGTG” name: genome: public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); while (…not end of file…) { Species current = new Species (…name…, …genome…); ss. insert (current); } } public class Species. Set { private Vector els; 5 void November 2002 public insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 13 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: “Goat” “CAGTG” name: genome: public class Phylogeny { static public void main (String args[]) { Species. Set ss = new Species. Set (); while (…not end of file…) { Species current = new Species (…name…, …genome…); ss. insert (current); } } public class Species. Set { private Vector els; 5 void November 2002 public insert (/*@non_null@*/ Species s) { if (get. Index (s) < 0) els. add (s); } CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 14 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species “Duck” els: ss: Species. Set Top of Stack “CATAG” name: genome: “Goat” Initialize Mark and Sweeper: active = all objects on stack “CAGTG” name: genome: 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 15 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack “Goat” while (!active. is. Empty ()) newactive = { } “CAGTG” foreach (Object a in active) mark a as reachable (non-garbage) name: foreach (Object o that a points to) genome: if o is not marked newactive = newactive U { o } active = newactive 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 16 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack “Goat” while (!active. is. Empty ()) newactive = { } “CAGTG” foreach (Object a in active) mark a as reachable (non-garbage) name: foreach (Object o that a points to) genome: if o is not marked newactive = newactive U { o } active = newactive 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 17 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack “Goat” while (!active. is. Empty ()) newactive = { } “CAGTG” foreach (Object a in active) mark a as reachable (non-garbage) name: foreach (Object o that a points to) genome: if o is not marked newactive = newactive U { o } active = newactive 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 18 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack “Goat” while (!active. is. Empty ()) newactive = { } “CAGTG” foreach (Object a in active) mark a as reachable (non-garbage) name: foreach (Object o that a points to) genome: if o is not marked newactive = newactive U { o } active = newactive 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 19 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack “Goat” while (!active. is. Empty ()) newactive = { } “CAGTG” foreach (Object a in active) mark a as reachable (non-garbage) name: foreach (Object o that a points to) genome: if o is not marked newactive = newactive U { o } active = newactive 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 20 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack while (!active. is. Empty ()) “Goat” newactive = { } foreach (Object a in active) “CAGTG” mark a as reachable foreach (Object o that a points to) name: if o is not marked genome: newactive = newactive U { o } active = newactive sweep () // remove unmarked objects on heap 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 21 “CGATG”
After main returns… “in. spc” Stack name: genome: Bottom of Stack Phylogeny. main String[]: args root: Species ss: Species. Set Top of Stack “Duck” els: “CATAG” name: genome: active = all objects on stack while (!active. is. Empty ()) “Goat” newactive = { } foreach (Object a in active) “CAGTG” mark a as reachable foreach (Object o that a points to) name: if o is not marked genome: newactive = newactive U { o } active = newactive sweep () // remove unmarked objects on heap 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 22 “CGATG”
Garbage Collection “in. spc” Stack name: genome: Bottom Topofof. Stack “Duck” els: “CATAG” name: genome: active = all objects on stack while (!active. is. Empty ()) “Goat” newactive = { } foreach (Object a in active) “CAGTG” mark a as reachable foreach (Object o that a points to) name: if o is not marked genome: newactive = newactive U { o } active = newactive sweep () // remove unmarked objects on heap 5 November 2002 CS 201 J Fall 2002 name: genome: “Elf” “Frog” “CGGTG” 23 “CGATG”
Problems with Mark and Sweep • Fragmentation: free space and alive objects will be mixed – Harder to allocate space for new objects – Poor locality means bad memory performance • Caches make it quick to load nearby memory • Multiple Threads – One stack per thread, one heap shared by all threads – All threads must stop for garbage collection 5 November 2002 CS 201 J Fall 2002 24
Stop and Copy • Solves fragmentation problem • Copy all reachable objects to a new memory area • After copying, reclaim the whole old heap • Disadvantages: – More complicated: need to change stack and internal object pointers to new heap – Need to save enough memory to copy – Expensive if most objects are not garbage 5 November 2002 CS 201 J Fall 2002 25
Generational Collectors • Observation: – Many objects are short-lived • Temporary objects that get garbage collected right away – Other objects are long-lived • Data that lives for the duration of execution • Separate storage into regions – Short term: collect frequently – Long term: collect infrequently • Stop and copy, but move copies into longer-lived areas 5 November 2002 CS 201 J Fall 2002 26
Reference Counting What if each object kept track of the number of references to it? If the object has zero references, it is garbage! 5 November 2002 CS 201 J Fall 2002 27
Referencing Counting T x = new T (); The x object has one reference y = x; The object x references has 1 more ref The object ypre references has 1 less ref } Leave scope where x is declared The object x references has 1 less ref 5 November 2002 CS 201 J Fall 2002 28
Reference Counting class Recycle { private String name; private Vector pals; public Recycle (String name) { this. name = name; pals = new Vector (); } public void add. Pal (Recycle r) { pals. add. Element (r); } “Alice” } public class Garbage { static public void main (String args[]) { Recycle alice = new Recycle ("alice"); Recycle bob = new Recycle ("bob"); bob. add. Pal (alice); alice = new Recycle ("coleen"); bob = new Recycle ("dave"); } } 5 November 2002 CS 201 J Fall 2002 name: pals: refs: 21 “Bob” name: pals: refs: 1 29
Reference Counting class Recycle { private String name; private Vector pals; public Recycle (String name) { this. name = name; pals = new Vector (); } public void add. Pal (Recycle r) { pals. add. Element (r); } “Alice” } public class Garbage { static public void main (String args[]) { Recycle alice = new Recycle ("alice"); Recycle bob = new Recycle ("bob"); bob. add. Pal (alice); alice = new Recycle ("coleen"); bob = new Recycle ("dave"); “Coleen” } } 5 November 2002 name: pals: CS 201 Jrefs: Fall 2002 1 name: pals: refs: 21 “Bob” name: pals: refs: 1 30
Reference Counting class Recycle { private String name; private Vector pals; public Recycle (String name) { this. name = name; pals = new Vector (); } public void add. Pal (Recycle r) { pals. add. Element (r); } “Alice” } public class Garbage { static public void main (String args[]) { Recycle alice = new Recycle ("alice"); Recycle bob = new Recycle ("bob"); bob. add. Pal (alice); alice = new Recycle ("coleen"); bob = new Recycle ("dave"); } } 5 November 2002 CS 201 J Fall 2002 name: pals: refs: 01 “Bob” name: pals: refs: 01 31
Circular References class Recycle { private String name; private Vector pals; public Recycle (String name) { this. name = name; pals = new Vector (); } public void add. Pal (Recycle r) { pals. add. Element (r); } “Alice” } public class Garbage { static public void main (String args[]) { Recycle alice = new Recycle ("alice"); Recycle bob = new Recycle ("bob"); bob. add. Pal (alice); alice. add. Pal (bob); alice = null; bob = null; } } 5 November 2002 CS 201 J Fall 2002 name: pals: refs: 21 “Bob” name: pals: refs: 1 2 32
Reference Counting Summary • Advantages – Can clean up garbage right away when the last reference is lost – No need to stop other threads! • Disadvantages – Need to store and maintain reference count – Some garbage is left to fester (circular references) – Memory fragmentation 5 November 2002 CS 201 J Fall 2002 33
Java’s Garbage Collector • Mark and Sweep collector • Before collecting an object, it will call finalize protected void finalize() throws Throwable • Can call garbage collector directly: System. gc () 5 November 2002 CS 201 J Fall 2002 34
Garbage in, Garbage out? class Recycle { private String name; private Vector pals; public Recycle (String name) { this. name = name; pals = new Vector (); } public void add. Pal (Recycle r) { pals. add. Element (r); } protected void finalize () { System. err. println (name + " is garbage!"); } } public class Garbage { static public void main (String args[]) { Recycle alice = new Recycle ("alice"); Recycle bob = new Recycle ("bob"); bob. add. Pal (alice); alice = new Recycle ("coleen"); System. gc (); bob = new Recycle ("dave"); System. gc (); } CS 201 J Fall 2002 } 5 November 2002 > java Garbage First collection: Second collection: alice is garbage! bob is garbage! 35
Testing Strategy The applicant's source code and documentation shall be reviewed to verify that the software conforms to the documentation and that the documentation is sufficient to enable the Division to design and conduct all tests at any level of the software structure to verify that the software meets the requirements and objectives of its design specification. Either the division staff or the ITA, which will conduct software qualification tests, shall witness compilation of the source code into baseline object code. The baseline object code and the object code tested must be identical. The object code tested and certified must be identical to the object code released. A copy of the baseline object code will be retained by the Division and used to verify that the baseline code, tested code, and the release code are identical. Once the Division has conducted a review of system software and documentation, test plans shall be designed to exercise all system functions controlled by software under nominal load and data conditions and throughout the range of conditions for which performance is claimed. The first phase of Florida Software Qualification Testing is designed to evaluate the system software’s functionality, and to establish baselines for the system being tested. … Florida Voting Systems Standard, 5 November 2002 CS 201 J Fall 2002 http: //election. dos. state. fl. us/laws/pdf/FVSS 402. pdf 36
Election Day • How much do you trust the programs in the voting machines to record your vote correctly? • How much do you trust the programs that tabulate the votes to count them correctly? Hint #1: These programs were probably written in C. Hint #2: These programs were probably not written by Libertarians. Hint #3: The authors of these programs didn’t pass CS 201 J and weren’t able to get more interesting, high-paying programming jobs. 5 November 2002 CS 201 J Fall 2002 37
Charge • In Java: be happy you have a garbage collector to clean up for you • In C: need to deallocate storage explicitly – Why is it hard to write a garbage collector for C? (next class) • In the real world: clean up after yourself and others! 5 November 2002 CS 201 J Fall 2002 Garbage Collectors (COAX, Seoul, 18 June 2002) 38
- Slides: 38