Copying Garbage Collector

Some advantages compared to mark-and-sweep:

  • no fragmentation
  • fast allocation, as in MallocInfMem.scala
  • good when a lot of data allocated and thrown away (as in functional languages)

Disadvantage: double space consumption

  • note that fragmentation can (very infriquently) mean inability to allocate block even if there is e.g. 1000 more space

Basic idea:

  • copy and compact useful data from from-space into the other half, to-space
    • in to-space we build (compactly laid out) isomorphic graph copy of graph in from-space
  • pronounce the other half empty and swap their roles


  • addresses of nodes change
  • must update all root pointers to new locations
  • must update reference fields of all non-garbage objects

Forwarding - key step (copies node if needed)

  • if p is a pointer in from-space, make it point into to-space
  • store in old copy where the new copy is (necessary for shared structures)

Consider example of moving a graph with sharing

Simple Collector

def forward(p) =
  if (p points to from-space) {
    if (p.f1 points to to-space) 
      p.f1 // moved already
    else {
      for (each field f_i of p) =
      p.f1 = next
      next = next + sizeof(p)
  } else p
def collect = {
  scan = beginning-of-to-space
  next = scan
  for (each root r)
    r = forward(r)
  while (scan < next)
    for (each field f_i of record at scan) = forward(
    scan = scan + sizeof(scan)

Note: for locality of reference want to do depth-first search instead