Free - Suif - Stanford University
Free - Suif - Stanford University
Free - Suif - Stanford University
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Jeffrey D. Ullman<br />
<strong>Stanford</strong> <strong>University</strong>
2<br />
• Programming is easier if the run-time system<br />
“garbage-collects” – makes space belonging to<br />
unusable data available for reuse.<br />
• Java does it; C does not.<br />
• But stack allocation in C gets some of the advantage.
1. Speed – low overhead for garbage collector.<br />
2. Little program interruption.<br />
• Many collectors shut down the program to hunt for<br />
garbage.<br />
3. Locality – data that is used together is placed<br />
together on pages, cache-lines.<br />
• If the garbage collector moves data, you have some<br />
choices where you put things.<br />
3
4<br />
• There is a root set of data that is a-priori<br />
reachable.<br />
• Example: In Java, root set = static class variables<br />
plus variables on run-time stack.<br />
• Reachable data: root set plus anything<br />
referenced by something reachable.<br />
• Question: Why doesn’t the notion of<br />
“reachability” make sense for C? Why is it<br />
OK for Java?
5<br />
• Things requiring space are “objects.”<br />
• Available space is in a heap – large area<br />
managed by the run-time system.<br />
• Allocator finds space for new objects.<br />
• Space for an object is a chunk.<br />
• Garbage collector finds unusable objects,<br />
returns their space to the heap, and maybe<br />
moves objects around in the heap.
6<br />
<strong>Free</strong> List<br />
. . .<br />
Object 1 Object 2<br />
Object 3
7<br />
1. Chunks are either allocated or free.<br />
2. <strong>Free</strong> chunks are linked in some sort of<br />
available space list.<br />
• Why do the links not waste space?<br />
3. Chunks record their length so you know where<br />
the next chunk begins.<br />
• Seems to waste space. Why needed?<br />
4. Adjacent free chunks may not be combined<br />
into one larger chunk.<br />
• Why would we let that happen?
8<br />
1. Via the free-space list.<br />
2. Following references in the objects that<br />
appear in the allocated chunks.<br />
3. In order through the heap.<br />
• That’s why it is useful to have the length of each<br />
chunk in the chunk itself.
• Typically a program needs chunks of various<br />
sizes.<br />
• Fragmentation problem: free chunks become<br />
small, disconnected pieces, so you can’t find<br />
space for a large object.<br />
• Allocation by best fit requires examination of<br />
the entire free list.<br />
• First fit is more efficient, but can give an object<br />
a much larger chunk than it needs.<br />
9
10<br />
• Option: keep many free lists, each with an<br />
exponentially growing range of sizes.<br />
• Then first-fit can’t waste more than 50% of the<br />
space.<br />
• If there are few classes, there will be few sizes of free<br />
chunks, so maybe no waste.<br />
• More extreme: allow only a fixed set of sizes,<br />
e.g., Fibonacci numbers.<br />
• Allocation is trivial since there is no decision.<br />
• But usually wastes space.
11<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based
12<br />
• The simplest (but imperfect) method is to<br />
give each object a reference count = number<br />
of references to this object.<br />
• Assumes objects have no internal references or<br />
these can be excluded.<br />
• Initially, object has one reference.<br />
• If reference count becomes 0, object is<br />
garbage and its space becomes available.
Integer i = new Integer(10);<br />
• Integer object is created with RC = 1.<br />
• Consider execution of j = k; (j, k are Integer<br />
references.)<br />
• Object referenced by j has RC--.<br />
• Object referenced by k has RC++.<br />
13
• If an object reaches RC=0, its chunk is garbagecollected<br />
(added to the free list), and the<br />
references within that object effectively<br />
disappear.<br />
• Follow these references and decrement RC in<br />
the objects reached.<br />
• That may result in more objects with RC=0,<br />
leading to recursive collection.<br />
14
15<br />
Root<br />
Object<br />
We remove<br />
this link during<br />
program<br />
execution<br />
A(1)<br />
B(2)<br />
E.g., object B has<br />
reference count 2,<br />
from A and D<br />
C(1)<br />
D(2)<br />
E(1)
16<br />
Root<br />
Object<br />
Reference count<br />
for A drops to zero<br />
A(0)<br />
B(2)<br />
C(1)<br />
D(2)<br />
E(1)
17<br />
Root<br />
Object<br />
So remove A.<br />
Reference count for C drops<br />
to zero, wile the count for<br />
B drops to 1.<br />
B(1)<br />
C(0)<br />
D(2)<br />
E(1)
18<br />
Root<br />
Object<br />
Remove C. Reference count<br />
for D drops to one<br />
B, D, and E are<br />
garbage, but their<br />
reference counts<br />
are all > 0. They<br />
never get collected.<br />
D(1)<br />
B(1)<br />
E(1)
19<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Basic
• Mark: Starting from the root set, search all<br />
references to discover reachable objects.<br />
• Sweep : Return all unreached objects to the free<br />
list.<br />
20
<strong>Free</strong> = not holding an object; available for<br />
allocation.<br />
Unreached = Holds an object, but has not yet<br />
been reached from the root set.<br />
Unscanned = Reached from the root set, but<br />
its references not yet followed.<br />
Scanned = Reached and references followed.<br />
21
1. Assume all objects in Unreached state.<br />
2. Start with the root set. Put them in state<br />
Unscanned.<br />
3. while Unscanned objects remain do<br />
examine one of these objects;<br />
make its state be Scanned;<br />
add all referenced objects to Unscanned<br />
list if they were previously Unreached;<br />
end;<br />
22
23<br />
• Place all objects still in the Unreached state into<br />
the <strong>Free</strong> state.<br />
• Question: how do we find all the chunks in the<br />
heap?<br />
• Place all objects in the Scanned state into the<br />
Unreached state.<br />
• To prepare for the next mark-and-sweep.
24<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Basic<br />
Baker’s
25<br />
• Problem: The basic algorithm takes time<br />
proportional to the heap size.<br />
• Because you must visit all objects to see if they are<br />
Unreached.<br />
• Baker’s algorithm keeps a list of all allocated<br />
chucks of memory, as well as the <strong>Free</strong> list.
26<br />
• Key change: In the sweep, look only at the<br />
list of allocated chunks.<br />
• Those that are not marked as Scanned are<br />
garbage and are moved to the <strong>Free</strong> list.<br />
• Those in the Scanned state are put in the<br />
Unreached state.<br />
• For the next collection.<br />
• Question: What is the downside to linking<br />
the allocated chunks?
27<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Basic Baker’s Basic
• Compact = move reachable objects to<br />
contiguous memory.<br />
1. Locality – fewer pages or cache-lines needed<br />
to hold the active data.<br />
2. Avoids fragmentation – after GC, the free<br />
space is one large chunk, so there is space to<br />
store large objects.<br />
28
29<br />
1. Mark reachable objects as before.<br />
2. Create a table (hash?) from reached chunks<br />
to new locations for the objects in those<br />
chunks.<br />
3. Scan chunks from low end of heap.<br />
4. Maintain pointer free that counts how much<br />
space is used by reached objects so far.<br />
• That is, free points to the first byte that has not<br />
been used for the reached objects so far.
30<br />
5. Move all reached objects to their new<br />
locations, and also retarget all references in<br />
those objects to the new locations.<br />
• Use the table of new locations.<br />
6. Retarget root references.
31<br />
Consider first chunk,<br />
but it is free, so skip<br />
over it<br />
free
32<br />
Enter into table that<br />
this is where the<br />
first object will go<br />
Consider first object<br />
free<br />
New address is<br />
current value of “free”
33<br />
Consider next chunk,<br />
but it is free<br />
free<br />
Advance “free” to<br />
next available byte
34<br />
Consider next chunk<br />
free<br />
New address is current “free”;<br />
enter that into table
35<br />
free<br />
Advance “free” to<br />
the next available byte
36<br />
Eventually advance to<br />
the next used chunk<br />
free<br />
New address is current “free”;<br />
enter that into table
37<br />
free<br />
Advance “free” to<br />
the next available byte
38<br />
Change internal pointer to<br />
second object to point to new<br />
location of second object<br />
Start the Compact phase.<br />
Move first object<br />
to its new location<br />
free
39<br />
Change internal pointer to<br />
third object to point to new<br />
location of third object<br />
Move second object<br />
to its new location<br />
free
40<br />
Change internal pointer to<br />
first object to point to new<br />
location of first object<br />
Move third object<br />
to its new location<br />
free
41<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Basic Baker’s Basic Cheney’s
• Uses 2 heaps.<br />
• Allocate space in one.<br />
• When the first is full, copy reachable objects<br />
to the second heap.<br />
• Then, swap roles.<br />
42
43<br />
• To copy: maintain table of new locations for<br />
the reachable objects.<br />
• As soon as an object is reached, give it the<br />
next available bytes in the second heap.<br />
• As you scan objects, adjust their references to<br />
point to second heap.<br />
• Trick: scan recursively, starting with the root<br />
objects, so by the time you finish with an object,<br />
all the objects it references have their new<br />
locations.
Object scan(Object: O) {<br />
select new location o for O in the other heap,<br />
and enter that location into table;<br />
for (each reference r in O to an object P)<br />
if (exists entry in the table for P)<br />
r = that entry;<br />
else<br />
r = scan(P);<br />
return o;<br />
}<br />
44
45<br />
• There is an analogy between program memory<br />
management and file-system disk<br />
management:<br />
• Heap :: volume or partition<br />
• Object :: file<br />
• Cache line or page :: track or cylinder
• A file system can also benefit from compaction,<br />
for faster file access, even if there is no need for<br />
GC.<br />
• Question: can you garbage collect a file system?<br />
• Modern distributed file systems replicate files in<br />
several places for availability and fault<br />
tolerance.<br />
• Consider a replicated volume holding many<br />
files.<br />
• Each copy of the volume holds the same files, but<br />
the location within the volume is unimportant.<br />
46
• Because the volume is replicated, we can take<br />
one copy “off-line” and compact it using the<br />
basic compaction algorithm.<br />
• Other copies are still available for reads and<br />
writes.<br />
• After the compacted copy of the volume comes<br />
back on-line, create within it copies of any files<br />
written to the other volume-copies while it was<br />
off-line.<br />
47
48<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Incremental<br />
Partial<br />
Basic Baker’s Basic Cheney’s
1. Incremental – run garbage collection in<br />
parallel with mutation (execution of the<br />
program).<br />
2. Partial – stop the mutation, but only briefly,<br />
to garbage collect a part of the heap.<br />
49
50<br />
• OK to mark garbage as reachable.<br />
• Not OK to GC a reachable object.<br />
• If a reference r within a Scanned object is<br />
mutated to point to an Unreached object,<br />
the latter may be garbage-collected anyway.<br />
• Subtlety: How can a reference be made to point<br />
to an Unreached object?<br />
• Answer: a new object O be created during the<br />
marking, and a scanned object may refer to O.
51<br />
• Intercept every write of a reference in a<br />
scanned object.<br />
• Place the new object referred to on the<br />
Unscanned list.<br />
• A trick: protect all pages containing Scanned<br />
objects.<br />
• A hardware interrupt will invoke the fixup.
52<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Incremental<br />
Partial<br />
Basic Baker’s Basic Cheney’s<br />
Generational
53<br />
• “Most objects die young.”<br />
• But those that survive one GC are likely to survive<br />
many.<br />
• Tailor GC to spend more time on regions of the<br />
heap where objects have just been created.<br />
• Gives a better ratio of reclaimed space per unit time.
54<br />
• We collect one part(ition) of the heap.<br />
• The target set.<br />
• Other objects are the stable set.<br />
• We maintain for each partition a remembered<br />
set of those objects in the stable set that refer<br />
to objects in the target set.<br />
• Write barriers can be used to maintain the<br />
remembered set.
55<br />
• To collect a part of the heap:<br />
1. Add the remembered set for that partition to the<br />
root set.<br />
2. Do a reachability analysis (mark) as before.<br />
• Note the resulting Scanned set may include<br />
garbage. Why?
56<br />
In the remembered set<br />
The target<br />
partition<br />
Not reached from<br />
the root set<br />
Stable set
57<br />
• Divide the heap into partitions P 0 , P 1 , …<br />
• Each partition holds older objects than the one before<br />
it.<br />
• Create new objects in P 0 , until it fills up.<br />
• Garbage collect P 0 only, and move the reachable<br />
objects to P 1 .<br />
• When P 1 fills, garbage collect P 0 and P 1 , and put<br />
the reachable objects in P 2 .<br />
• In general: When P i fills, collect P 0 , P 1 , … ,P i and<br />
put the reachable objects in P i +1 .
58<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Incremental<br />
Partial<br />
Basic Baker’s Basic Cheney’s<br />
Generational<br />
Train
59<br />
• Problem with generational GC:<br />
1. Occasional total collection (last partition).<br />
2. Long-lived objects move many times.<br />
• Train algorithm useful for long-lived objects.<br />
• Replaces higher-numbered partitions in<br />
generational GC.<br />
• I.e., first partition is not part of the “train,” and is used for<br />
new objects just as in the previous algorithm.
60<br />
Train 1<br />
Car 11<br />
Car 12<br />
Car 13<br />
Train 2<br />
.<br />
.<br />
.<br />
Car 21<br />
Car 22<br />
. . .<br />
Car 2k<br />
Train n<br />
Car n1<br />
Car n2
61<br />
• There can be any number of trains, and each<br />
train can have any number of cars.<br />
• You need to decide on a policy that gives a<br />
reasonable number of each.<br />
• Objects entering the system can:<br />
• Be placed in the last car of the last train,<br />
• Or start a new car at the end of the last train,<br />
• Or even start a new train (which becomes the last).
62<br />
• Each car has a remembered set of references<br />
from<br />
1. Higher-numbered trains and<br />
2. Higher-numbered cars of the same train.<br />
• Important: since we only garbage-collect first<br />
cars and first trains, we never need to worry<br />
about “forward” references (to later trains or<br />
later cars of the same train).
63<br />
1. Collect the first car of the first train.<br />
• Like we collect P 0 in generational GC.<br />
2. Collect the entire first train if there are no<br />
references from the root set or other trains.<br />
• This is how we find and eliminate large, cyclic<br />
garbage structures.
1. Do a partial collection as before, using<br />
every other car/train as the stable set.<br />
2. Move all Scanned (reachable) objects of<br />
the first car somewhere else.<br />
3. Get rid of the car.<br />
64
65<br />
• If object o has a reference from another train,<br />
pick one such train and move o to that train.<br />
• Same car as reference, if possible, else make new<br />
car.<br />
• If references only from root set or first train,<br />
move o to another car of first train, or create<br />
new car.
66<br />
• The problem: it is possible that when collecting<br />
the first car, nothing is garbage.<br />
• We may then create a new last car of the first<br />
train with the same objects as the old first car.<br />
• Situation is rare, but possible, requiring:<br />
1. A cyclic, but nongarbage structure in the first train.<br />
2. A mutator that changes references to the first train<br />
with perfect timing so that we never see anything<br />
in the remembered sets for the first car from<br />
outside the first train.
67<br />
• If that happens, we go into panic mode, which<br />
requires that:<br />
1. If a reference to any object in the first train is<br />
rewritten, we make the new reference a “dummy”<br />
member of the root set.<br />
2. During panic-mode GC, if we encounter a<br />
reference from the dummy “root set,” we move<br />
the referenced object to another train.<br />
• Eventually, all reachable objects will leave the<br />
first train, leaving cyclic garbage, and we can<br />
delete the first train.
68<br />
Garbage Collectors<br />
Reference-<br />
Counters<br />
Trace-<br />
Based<br />
Stop-the-World<br />
Short-Pause<br />
Mark-and-<br />
Sweep<br />
Mark-and-<br />
Compact<br />
Incremental<br />
Partial<br />
Basic Baker’s Basic Cheney’s<br />
Generational<br />
Train