SlideShare a Scribd company logo
1 of 14
Download to read offline
Garbage collection

   Garbage Collection                                  In L3, the storage for some values does not
                                                       follow a stack discipline for its allocation and
                                                       deallocation


   15-745 Optimizing Compilers                                                      intlist* f(int x) {
                                                      struct intlist {                  var l1: intlist;
                                                          val: int;                     var l2: intlist*;
                                                          next: intlist*;             …
                                                       };                               l2 = alloc(…);
                                                                                      …
                                                                                        return l2;
                                                                                    }
Spring 2006




     Reclaiming heap storage                          Explicit deallocation

     If we do nothing to reclaim heap storage after    Explicit deallocation is
     it is used, then eventually some programs will
     (needlessly) exhaust memory                          • a dangerous source of bizarre bugs

     Several partial solutions:                           • highly prone to error
        • explicit deallocation (“free(l)”)               • slow
        • reference counting
        • tracing garbage collector                    As such, it is a stupid feature for the
        • conservative garbage collector               vast majority of programming tasks.
        • memory mgmt based on region analysis         We will not consider it further.
Reference counting

                                               Basic idea:
                                                    • add an extra integer (the “reference count”) to
                                                      every heap-allocated data structure
                                                    • when first allocated, initialize the reference
        Reference Counting                            count to 1
                                                    • whenever a new reference to the data structure
                                                      is established, increment the reference count
                                                    • whenever a reference disappears, decrement the
                                                      reference count and check if it is zero
                                                        • if it is zero, then reclaim the storage




  Reference counting example                   Reference counting example
var   l: intlist*;                           var   l: intlist*;
var   m: intlist*;                           var   m: intlist*;
var   n: intlist*;                           var   n: intlist*;
l =   alloc(…);      12
                     /     …       null      l =   alloc(…);                    112
                                                                                 / /        …       null

if (…) {                                     if (…) {
  m = l;                                       m = l;
  …                                            …
} else {                                     } else {
  n = alloc(…);       12
                      /        …      null     n = alloc(…);                           12
                                                                                       /        …      null
  l->next = n;                                 l->next = n;
  …                                            …
}                                            }                                     1        …        null
l = alloc(…);                                l = alloc(…);
RC is naïve                                             RC is broken
Reference counting has been (re)invented
many, many times                                            More importantly, for most programming
                                                            language applications, reference counting
It is often the first idea that comes to mind for           doesn’t work well for cyclic structures.
dynamic memory management and has the                         • several techniques for this, but hard and messy
advantage of simplicity
   • also real-time behavior
                                                        x
   • also, objects stay in one place                                        2      …

However, it is inefficient
   • in storage, because of the reference counts, and
                                                                                           1      …
   • in speed, because of the need always to maintain          1      …
     the counts




                                                        Mark and Sweep
                                                        Basic idea:
                                                             • maintain a linked list, called the free list, that
                                                               contains all of the heap blocks that can be allocated
                                                             • if the program requests a heap block but the free list
          Mark and Sweep                                       is empty, invoke the garbage collector
                                                                  • starting from the roots, trace and mark all
                                                                    reachable heap blocks
                                                                  • sweep and collect all unmarked heap blocks,
                                                                    putting each one back on the free list
                                                                  • sweep again, unmarking all heap blocks

                                                             • first developed by McCarthy in 1960
Free lists                                           Roots
                                                    We need to find all heap blocks that might still
Suppose that every allocated heap block is          be used by the program
two words long
                                                       • if one of the program’s live variables points to a heap
                                                         block, then that heap block plus all of the heap
Then a free list is simply a linked list of these        blocks that it (directly or indirectly) points to could
blocks                                                   (conservatively) be used in the future


In practice, can have separate free lists for       To find all of these blocks, we must start with
2, 4, 8, … -word blocks                             the heap pointers that currently exist in the
                                                    registers and run-time stack
                                                       • these are called the root pointers
                                                       • the root pointers point to the pointer graph




Finding roots                                        Pointers vs non-pointers
                                                    Two main approaches:
Which registers and stack slots
contain heap pointers?                                • Every word value uses a tag bit
                                                         • eg: low-order bit = 0 means pointer, low-
   • not a trivial question, because pointers              order bit = 1 means non-pointer
     and non-pointers are indistinguishable              • Each heap block uses its first word to record
                                                           the length of the block
Note that we only need to know this at              or…
each heap-allocation point. Why?
                                                      • For each call to _alloc(), the compiler emits a
                                                        bit string that tells which registers contain
Essentially, findings roots comes down                  heap pointers
to deciding whether a word value is or                   • a bit string is also emitted for each
isn’t a pointer                                             procedure, to declare which stack slots
                                                            contain pointers
Mark and Sweep                                               Tracing
Basic idea:
                                                             How to trace the pointer graph?
  • maintain a linked list, called the free list, that
    contains all of the heap blocks that can be allocated      • could do a depth-first or breadth-first
  • if the program requests a heap block but the free list       traversal
    is empty, invoke the garbage collector
       • starting from the roots, trace and mark all
                                                             But if we are truly out of memory, we
         reachable heap blocks
       • sweep and collect all unmarked heap blocks,
                                                             will not have space for the
         putting each one back on the free list              stack/queue!
       • sweep again, unmarking all heap blocks
                                                               • how large could the stack/queue get?




Pointer reversal                                             Pointer reversal example

 root                                                                    root
                             The basic idea is to do
                             a depth-first traversal,
                             and encode the stack in
                             the pointer graph itself,
                             by reversing pointers as
                             we go
Pointer reversal example   Pointer reversal example

        root                       root




Pointer reversal example   Pointer reversal example

        root                       root
Pointer reversal example   Pointer reversal example

        root                       root




Pointer reversal example   Pointer reversal example

        root                       root
Pointer reversal example   Pointer reversal example

        root                       root




Pointer reversal example   Pointer reversal example

        root                       root
Marking                                   How fast is mark-and-sweep?
                                         Assume all heap blocks are the same
Where to put the mark bits?              size. Let
                                            • c1 = the cost to trace and mark a heap
If we use a header word for every             block
heap block, then can use a bit in the       • c2 = the cost to put a heap block back on
header word                                   the free list
                                            • H = the size of the heap, in terms of
                                              number of heap blocks
Can also use a table of mark bits
                                            • R = the number of reachable heap blocks
                                         Then the cost to reclaim a heap block is




                                          Copying collection
                                        Basic idea:
                                          • two heaps, called from-space and to-space
                                          • allocate heap blocks in the from-space, from low
                                            memory to high memory
       Stop and Copy                      • when from-space is exhausted, trace the pointer
                                            graph (starting from the roots) and copy all
                                            reachable data to to-space
                                              • leave a forwarding address in the from-space

                                          • when all done copying, flip, so that to-space is
                                            now from-space and vice-versa

                                        First proposed by Fenichel & Yochelson in
                                        1969
Classical copying algorithm                                Copying collection is fast
   HP


                                                               Note that heap allocation is simply:
                                                                 • increment the heap pointer, HP
                             next
roots                                                            • check whether it is in bounds, and if not,
                            scan
                                                                   invoke GC
             from                          to

 GC() {                              forward(p) {              What is the cost to reclaim a heap block?
   scan = next = start of to-space     if (p in from-space)
   for each root p {
     forward(p);
                                         if (*p in to-space)
                                           return *p
                                                                 • assume cost c to trace a reachable block
   }                                     else {
   while (scan < next) {                   *next = *p;
     *scan = forward (scan++);             *p = next++;                             What is the limit, as H!"?
   }                                       return *p;
   flip();                               }
 }                                     else return p;
                                     }




    Notes

        Like mark-and-sweep, we still need to
        find roots and distinguish pointers
        from non-pointers

        How to do the heap check?
                                                                 Generation Scavenging
          • overflow method
             • let M=max heap address, B=base
               heap address
             • then HPi=maxint-(M-B)

          • page-protection method
             • usually not precise for most OS’s
Generational GC                                           Nursery and tenured spaces

        Two observations by Hewitt in 1987:                   The nursery is very small (<1MB), and
                                                              mostly garbage (because objects die
          • most heap-allocated objects die young
                                                              young)
          • newer objects usually point to older
            objects                                             • therefore, copying collection is fast

        Basic idea of generational GC:                        If objects get promoted to the tenured
                                                              space, they are unlikely to point to
          • a small pair of heaps, called the nursery         nursery objects
          • if copying collection in the nursery is
            ineffective, then copy to a bigger pair of          • therefore, nursery collection can
            heaps, called the tenured space                       (mostly) ignore objects in the tenured
                                                                  space




    Nursery and tenured spaces                                Some details
   HP
                                                              GC in the nursery is called “minor”; in
                                                              the tenured space it is called “major”
                                                    nursery
                       limit
roots                                                         Can set a percentage limit for the
                       next
                                                              tenure decision:
             from                    to
    HP                                                          • when nursery is X% full after minor GC,
                                                                  then copy to tenured space

                                                    tenured   It is also possible to have more than
                                                              two generations, though tends not to
                                                              be profitable
                from                      to
The write barrier                               In practice

The main problem with generational GC
occurs when/if pointers in the tenured
space point to objects in the nursery
  • how can this happen?
                                                 In practice, generational GC is incredibly
                                                 effective, even for imperative languages
We need to trace these pointers during
minor collections
  • maintain a store list, which contains the
    addresses of every heap block that has
    been modified
  • this means that every write to the heap
    must update the store list




                                                Concurrent GC
                                                Baker in 1981 devised an extension to
                                                copying collection to make it concurrent,
                                                in the sense that every call to alloc()
                                                would be guaranteed to execute less
         Concurrent GC                          than a (small) constant number of
                                                instructions

                                                Basic idea:
                                                  • every time a pointer is dereferenced, copy
                                                    its heap block, plus a few more heap
                                                    blocks, to the to-space
                                                      • flip if there is nothing left in from-space
Read barrier
Baker’s algorithm requires extra work
for every read of a heap pointer
This is incredibly expensive
But we avoid the long pause times of the         Conservative GC
simple copying collection algorithm
Later improvements eliminate the read
barrier, but with some complications
  • Nettles and O’Toole
  • Cheng and Blelloch




Conservative GC                            Boehm-Weiser GC

 “Conservative GC” is a misnomer, as       Basic idea:
 all garbage collection algorithms are
                                             • Put the heap in high memory
 conservative
                                                • so, few program integers are valid
                                                  heap addresses
 But some algorithms are inexact in the
                                             • Assume all values that could be aligned
 sense that they don’t try to do an            heap addresses are in fact heap
 accurate trace of the pointer graph           addresses
                                             • Instrument malloc() to keep track of
 The Boehm-Weiser collector that we            what has been allocated
 have provided for your use is just such
                                             • Then, do mark-and-sweep
 a garbage collector
                                                • why not do copying collection?
Boehm-Weiser                              Region-based mem mgmt

As long as no live heap block is          To be discussed in readings…
pointed to only by an interior pointer,
the mark-and-sweep will safely
reclaim only garbage

Furthermore, this has the advantage
that it will work with most C programs

However, it is fairly slow because of
the use of mark-and-sweep

More Related Content

What's hot

scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
Hiroshi Ono
 
Objective-C: a gentle introduction
Objective-C: a gentle introductionObjective-C: a gentle introduction
Objective-C: a gentle introduction
Gabriele Petronella
 
Introduction to scala for a c programmer
Introduction to scala for a c programmerIntroduction to scala for a c programmer
Introduction to scala for a c programmer
Girish Kumar A L
 
Everybody be cool, this is a roppery!
Everybody be cool, this is a roppery!Everybody be cool, this is a roppery!
Everybody be cool, this is a roppery!
zynamics GmbH
 
flatMap Oslo presentation slides
flatMap Oslo presentation slidesflatMap Oslo presentation slides
flatMap Oslo presentation slides
Martin Odersky
 
Mysterious c++
Mysterious c++Mysterious c++
Mysterious c++
xprayc
 
Platform-independent static binary code analysis using a meta-assembly language
Platform-independent static binary code analysis using a meta-assembly languagePlatform-independent static binary code analysis using a meta-assembly language
Platform-independent static binary code analysis using a meta-assembly language
zynamics GmbH
 

What's hot (18)

scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scala.reflect, Eugene Burmako
scala.reflect, Eugene Burmakoscala.reflect, Eugene Burmako
scala.reflect, Eugene Burmako
 
Aggregate Programming in Scala
Aggregate Programming in ScalaAggregate Programming in Scala
Aggregate Programming in Scala
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzer
 
Objective-C: a gentle introduction
Objective-C: a gentle introductionObjective-C: a gentle introduction
Objective-C: a gentle introduction
 
Introduction to scala for a c programmer
Introduction to scala for a c programmerIntroduction to scala for a c programmer
Introduction to scala for a c programmer
 
Scalax
ScalaxScalax
Scalax
 
Smart pointers
Smart pointersSmart pointers
Smart pointers
 
Devoxx
DevoxxDevoxx
Devoxx
 
Everybody be cool, this is a roppery!
Everybody be cool, this is a roppery!Everybody be cool, this is a roppery!
Everybody be cool, this is a roppery!
 
flatMap Oslo presentation slides
flatMap Oslo presentation slidesflatMap Oslo presentation slides
flatMap Oslo presentation slides
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency Constructs
 
Mysterious c++
Mysterious c++Mysterious c++
Mysterious c++
 
Best practices in Java
Best practices in JavaBest practices in Java
Best practices in Java
 
Platform-independent static binary code analysis using a meta-assembly language
Platform-independent static binary code analysis using a meta-assembly languagePlatform-independent static binary code analysis using a meta-assembly language
Platform-independent static binary code analysis using a meta-assembly language
 
Quick introduction to scala
Quick introduction to scalaQuick introduction to scala
Quick introduction to scala
 
Preparing Java 7 Certifications
Preparing Java 7 CertificationsPreparing Java 7 Certifications
Preparing Java 7 Certifications
 
Ow2 Utilities - The Swiss Army Knife Of Ow2 Projects
Ow2 Utilities - The Swiss Army Knife Of Ow2 ProjectsOw2 Utilities - The Swiss Army Knife Of Ow2 Projects
Ow2 Utilities - The Swiss Army Knife Of Ow2 Projects
 

Similar to Garbage

Collections in java
Collections in javaCollections in java
Collections in java
kejpretkopet
 
Collections In Java
Collections In JavaCollections In Java
Collections In Java
Binoj T E
 
Questions datastructures-in-c-languege
Questions datastructures-in-c-languegeQuestions datastructures-in-c-languege
Questions datastructures-in-c-languege
bhargav0077
 

Similar to Garbage (20)

DEF CON 27 - DIMITRY SNEZHKOV - zombie ant farm practical tips
DEF CON 27 - DIMITRY SNEZHKOV - zombie ant farm practical tipsDEF CON 27 - DIMITRY SNEZHKOV - zombie ant farm practical tips
DEF CON 27 - DIMITRY SNEZHKOV - zombie ant farm practical tips
 
Garbage collection 介紹
Garbage collection 介紹Garbage collection 介紹
Garbage collection 介紹
 
Sparse Data Support in MLlib
Sparse Data Support in MLlibSparse Data Support in MLlib
Sparse Data Support in MLlib
 
Memory Management In Python The Basics
Memory Management In Python The BasicsMemory Management In Python The Basics
Memory Management In Python The Basics
 
garbage collection in c ++.ppt
garbage collection in c ++.pptgarbage collection in c ++.ppt
garbage collection in c ++.ppt
 
LISP: How I Learned To Stop Worrying And Love Parantheses
LISP: How I Learned To Stop Worrying And Love ParanthesesLISP: How I Learned To Stop Worrying And Love Parantheses
LISP: How I Learned To Stop Worrying And Love Parantheses
 
Collections
CollectionsCollections
Collections
 
Collections in java
Collections in javaCollections in java
Collections in java
 
Collections In Java
Collections In JavaCollections In Java
Collections In Java
 
Ahieving Performance C#
Ahieving Performance C#Ahieving Performance C#
Ahieving Performance C#
 
Arrays in database systems, the next frontier?
Arrays in database systems, the next frontier?Arrays in database systems, the next frontier?
Arrays in database systems, the next frontier?
 
Hippo meetup: enterprise search with Solr and elasticsearch
Hippo meetup: enterprise search with Solr and elasticsearchHippo meetup: enterprise search with Solr and elasticsearch
Hippo meetup: enterprise search with Solr and elasticsearch
 
Smashing the stack with Hydra
Smashing the stack with HydraSmashing the stack with Hydra
Smashing the stack with Hydra
 
The Joy of SciPy
The Joy of SciPyThe Joy of SciPy
The Joy of SciPy
 
owasp lithuania chapter - exploit vs anti-exploit
owasp lithuania chapter - exploit vs anti-exploitowasp lithuania chapter - exploit vs anti-exploit
owasp lithuania chapter - exploit vs anti-exploit
 
Questions datastructures-in-c-languege
Questions datastructures-in-c-languegeQuestions datastructures-in-c-languege
Questions datastructures-in-c-languege
 
Kaggle tokyo 2018
Kaggle tokyo 2018Kaggle tokyo 2018
Kaggle tokyo 2018
 
Number Crunching in Python
Number Crunching in PythonNumber Crunching in Python
Number Crunching in Python
 
Clojure intro
Clojure introClojure intro
Clojure intro
 
Be a Zen monk, the Python way
Be a Zen monk, the Python wayBe a Zen monk, the Python way
Be a Zen monk, the Python way
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Recently uploaded (20)

MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 

Garbage

  • 1. Garbage collection Garbage Collection In L3, the storage for some values does not follow a stack discipline for its allocation and deallocation 15-745 Optimizing Compilers intlist* f(int x) { struct intlist { var l1: intlist; val: int; var l2: intlist*; next: intlist*; … }; l2 = alloc(…); … return l2; } Spring 2006 Reclaiming heap storage Explicit deallocation If we do nothing to reclaim heap storage after Explicit deallocation is it is used, then eventually some programs will (needlessly) exhaust memory • a dangerous source of bizarre bugs Several partial solutions: • highly prone to error • explicit deallocation (“free(l)”) • slow • reference counting • tracing garbage collector As such, it is a stupid feature for the • conservative garbage collector vast majority of programming tasks. • memory mgmt based on region analysis We will not consider it further.
  • 2. Reference counting Basic idea: • add an extra integer (the “reference count”) to every heap-allocated data structure • when first allocated, initialize the reference Reference Counting count to 1 • whenever a new reference to the data structure is established, increment the reference count • whenever a reference disappears, decrement the reference count and check if it is zero • if it is zero, then reclaim the storage Reference counting example Reference counting example var l: intlist*; var l: intlist*; var m: intlist*; var m: intlist*; var n: intlist*; var n: intlist*; l = alloc(…); 12 / … null l = alloc(…); 112 / / … null if (…) { if (…) { m = l; m = l; … … } else { } else { n = alloc(…); 12 / … null n = alloc(…); 12 / … null l->next = n; l->next = n; … … } } 1 … null l = alloc(…); l = alloc(…);
  • 3. RC is naïve RC is broken Reference counting has been (re)invented many, many times More importantly, for most programming language applications, reference counting It is often the first idea that comes to mind for doesn’t work well for cyclic structures. dynamic memory management and has the • several techniques for this, but hard and messy advantage of simplicity • also real-time behavior x • also, objects stay in one place 2 … However, it is inefficient • in storage, because of the reference counts, and 1 … • in speed, because of the need always to maintain 1 … the counts Mark and Sweep Basic idea: • maintain a linked list, called the free list, that contains all of the heap blocks that can be allocated • if the program requests a heap block but the free list Mark and Sweep is empty, invoke the garbage collector • starting from the roots, trace and mark all reachable heap blocks • sweep and collect all unmarked heap blocks, putting each one back on the free list • sweep again, unmarking all heap blocks • first developed by McCarthy in 1960
  • 4. Free lists Roots We need to find all heap blocks that might still Suppose that every allocated heap block is be used by the program two words long • if one of the program’s live variables points to a heap block, then that heap block plus all of the heap Then a free list is simply a linked list of these blocks that it (directly or indirectly) points to could blocks (conservatively) be used in the future In practice, can have separate free lists for To find all of these blocks, we must start with 2, 4, 8, … -word blocks the heap pointers that currently exist in the registers and run-time stack • these are called the root pointers • the root pointers point to the pointer graph Finding roots Pointers vs non-pointers Two main approaches: Which registers and stack slots contain heap pointers? • Every word value uses a tag bit • eg: low-order bit = 0 means pointer, low- • not a trivial question, because pointers order bit = 1 means non-pointer and non-pointers are indistinguishable • Each heap block uses its first word to record the length of the block Note that we only need to know this at or… each heap-allocation point. Why? • For each call to _alloc(), the compiler emits a bit string that tells which registers contain Essentially, findings roots comes down heap pointers to deciding whether a word value is or • a bit string is also emitted for each isn’t a pointer procedure, to declare which stack slots contain pointers
  • 5. Mark and Sweep Tracing Basic idea: How to trace the pointer graph? • maintain a linked list, called the free list, that contains all of the heap blocks that can be allocated • could do a depth-first or breadth-first • if the program requests a heap block but the free list traversal is empty, invoke the garbage collector • starting from the roots, trace and mark all But if we are truly out of memory, we reachable heap blocks • sweep and collect all unmarked heap blocks, will not have space for the putting each one back on the free list stack/queue! • sweep again, unmarking all heap blocks • how large could the stack/queue get? Pointer reversal Pointer reversal example root root The basic idea is to do a depth-first traversal, and encode the stack in the pointer graph itself, by reversing pointers as we go
  • 6. Pointer reversal example Pointer reversal example root root Pointer reversal example Pointer reversal example root root
  • 7. Pointer reversal example Pointer reversal example root root Pointer reversal example Pointer reversal example root root
  • 8. Pointer reversal example Pointer reversal example root root Pointer reversal example Pointer reversal example root root
  • 9. Marking How fast is mark-and-sweep? Assume all heap blocks are the same Where to put the mark bits? size. Let • c1 = the cost to trace and mark a heap If we use a header word for every block heap block, then can use a bit in the • c2 = the cost to put a heap block back on header word the free list • H = the size of the heap, in terms of number of heap blocks Can also use a table of mark bits • R = the number of reachable heap blocks Then the cost to reclaim a heap block is Copying collection Basic idea: • two heaps, called from-space and to-space • allocate heap blocks in the from-space, from low memory to high memory Stop and Copy • when from-space is exhausted, trace the pointer graph (starting from the roots) and copy all reachable data to to-space • leave a forwarding address in the from-space • when all done copying, flip, so that to-space is now from-space and vice-versa First proposed by Fenichel & Yochelson in 1969
  • 10. Classical copying algorithm Copying collection is fast HP Note that heap allocation is simply: • increment the heap pointer, HP next roots • check whether it is in bounds, and if not, scan invoke GC from to GC() { forward(p) { What is the cost to reclaim a heap block? scan = next = start of to-space if (p in from-space) for each root p { forward(p); if (*p in to-space) return *p • assume cost c to trace a reachable block } else { while (scan < next) { *next = *p; *scan = forward (scan++); *p = next++; What is the limit, as H!"? } return *p; flip(); } } else return p; } Notes Like mark-and-sweep, we still need to find roots and distinguish pointers from non-pointers How to do the heap check? Generation Scavenging • overflow method • let M=max heap address, B=base heap address • then HPi=maxint-(M-B) • page-protection method • usually not precise for most OS’s
  • 11. Generational GC Nursery and tenured spaces Two observations by Hewitt in 1987: The nursery is very small (<1MB), and mostly garbage (because objects die • most heap-allocated objects die young young) • newer objects usually point to older objects • therefore, copying collection is fast Basic idea of generational GC: If objects get promoted to the tenured space, they are unlikely to point to • a small pair of heaps, called the nursery nursery objects • if copying collection in the nursery is ineffective, then copy to a bigger pair of • therefore, nursery collection can heaps, called the tenured space (mostly) ignore objects in the tenured space Nursery and tenured spaces Some details HP GC in the nursery is called “minor”; in the tenured space it is called “major” nursery limit roots Can set a percentage limit for the next tenure decision: from to HP • when nursery is X% full after minor GC, then copy to tenured space tenured It is also possible to have more than two generations, though tends not to be profitable from to
  • 12. The write barrier In practice The main problem with generational GC occurs when/if pointers in the tenured space point to objects in the nursery • how can this happen? In practice, generational GC is incredibly effective, even for imperative languages We need to trace these pointers during minor collections • maintain a store list, which contains the addresses of every heap block that has been modified • this means that every write to the heap must update the store list Concurrent GC Baker in 1981 devised an extension to copying collection to make it concurrent, in the sense that every call to alloc() would be guaranteed to execute less Concurrent GC than a (small) constant number of instructions Basic idea: • every time a pointer is dereferenced, copy its heap block, plus a few more heap blocks, to the to-space • flip if there is nothing left in from-space
  • 13. Read barrier Baker’s algorithm requires extra work for every read of a heap pointer This is incredibly expensive But we avoid the long pause times of the Conservative GC simple copying collection algorithm Later improvements eliminate the read barrier, but with some complications • Nettles and O’Toole • Cheng and Blelloch Conservative GC Boehm-Weiser GC “Conservative GC” is a misnomer, as Basic idea: all garbage collection algorithms are • Put the heap in high memory conservative • so, few program integers are valid heap addresses But some algorithms are inexact in the • Assume all values that could be aligned sense that they don’t try to do an heap addresses are in fact heap accurate trace of the pointer graph addresses • Instrument malloc() to keep track of The Boehm-Weiser collector that we what has been allocated have provided for your use is just such • Then, do mark-and-sweep a garbage collector • why not do copying collection?
  • 14. Boehm-Weiser Region-based mem mgmt As long as no live heap block is To be discussed in readings… pointed to only by an interior pointer, the mark-and-sweep will safely reclaim only garbage Furthermore, this has the advantage that it will work with most C programs However, it is fairly slow because of the use of mark-and-sweep