Concurrent Reference Countingmaon/teaching/2014-2015/seminar/... · Table of contents 1...

Post on 14-Mar-2020

4 views 0 download

transcript

Concurrent Reference Counting

Or Ostrovsky

13/1/15

Or Ostrovsky Concurrent Reference Counting 13/1/15 1 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 2 / 57

The next 80 minutes in one slide

Goal - Applying reference counting to multithreaded scenariosTry use it out of the box, fail and understand whyImprove until we get it right

I Lock the whole objectI Lock a part of the objectI Log changes locally and apply them globallyI Snapshot the heap concurrentlyI Use single-threaded algorithms on the snapshot

Or Ostrovsky Concurrent Reference Counting 13/1/15 3 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 4 / 57

Ground rules

The invariantAn object’s reference count is equal to the number of references to thatobject.

The weaker invariantIf an object has references, it’s reference count won’t be 0.If an object doesn’t have references, it’s reference count willeventually be 0.

DisclaimerWe are not concerned about mutator correctness. Only the heap matters!

Or Ostrovsky Concurrent Reference Counting 13/1/15 5 / 57

The old algorithm

Algorithm 1 Non-concurrent reference counting operations

1: Write(o, i, ref):2: addReference(ref)3: old ← o[i]4: deleteReference(old)5: o[i] ← ref6:

7: Read(o, i):8: ref ← o[i]9: addReference(ref)

10: return ref

Or Ostrovsky Concurrent Reference Counting 13/1/15 6 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)

addReference(x) addReference(y)old ← o[i] old ← o[i]deleteReference(old) deleteReference(old)o[i] ← x o[i] ← y

o[i]

0x

1z

0y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)addReference(x) addReference(y)

old ← o[i] old ← o[i]deleteReference(old) deleteReference(old)o[i] ← x o[i] ← y

o[i]

1x

1z

1y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)addReference(x) addReference(y)old ← o[i] old ← o[i]

deleteReference(old) deleteReference(old)o[i] ← x o[i] ← y

o[i]

1x

1z

1y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)addReference(x) addReference(y)old ← o[i] old ← o[i]deleteReference(old) deleteReference(old)

o[i] ← x o[i] ← y

o[i]

1x

-1z

1y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)addReference(x) addReference(y)old ← o[i] old ← o[i]deleteReference(old) deleteReference(old)o[i] ← x

o[i] ← y

o[i]

1x

-1z

1y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Faces new problems

Thread 1 Write(o,i,x) Thread 2 Write(o,i,y)addReference(x) addReference(y)old ← o[i] old ← o[i]deleteReference(old) deleteReference(old)o[i] ← x o[i] ← y

o[i]

1x

-1z

1y

old 1 old 2

Or Ostrovsky Concurrent Reference Counting 13/1/15 7 / 57

Let’s break it down

Updating a reference count requires:I Update the PointerI Decrement the old target’s ref. countI Increment the new target’s ref. countI All must be coordinated!

Pitfalls:I Premature releaseI Garbage remaining indefinitely

Or Ostrovsky Concurrent Reference Counting 13/1/15 8 / 57

Table of contents

1 Introduction

2 Simple Reference CountingLocksAtomic Memory Primitives

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 9 / 57

Motivation

ProblemMultiple threads are accessing the same object at the same time.

SolutionAllow only one thread to access each object at a given time.

MethodProtect the object using locks

Or Ostrovsky Concurrent Reference Counting 13/1/15 10 / 57

Motivation

ProblemMultiple threads are accessing the same object at the same time.

SolutionAllow only one thread to access each object at a given time.

MethodProtect the object using locks

Or Ostrovsky Concurrent Reference Counting 13/1/15 10 / 57

Motivation

ProblemMultiple threads are accessing the same object at the same time.

SolutionAllow only one thread to access each object at a given time.

MethodProtect the object using locks

Or Ostrovsky Concurrent Reference Counting 13/1/15 10 / 57

The old algorithm revisitedAlgorithm 2 Eager reference counting with locks

1: Read(src, i):2: lock(src)3: tgt ← src[i]4: addReference(tgt)5: unlock(src)6: return ref7:

8: Write(src, i, ref):9: addReference(ref)

10: lock(src)11: old ← src[i]12: src[i] ← ref13: deleteReference(old)14: unlock(src)

Or Ostrovsky Concurrent Reference Counting 13/1/15 11 / 57

Analysis

Pro.SimpleWorks

Con.Performance - locks the whole object

Or Ostrovsky Concurrent Reference Counting 13/1/15 12 / 57

Motivation

ProblemLocking the whole object impedes performance.

SolutionLock the bare minimum needed.

MethodUse atomic memory primitives.

Or Ostrovsky Concurrent Reference Counting 13/1/15 13 / 57

Motivation

ProblemLocking the whole object impedes performance.

SolutionLock the bare minimum needed.

MethodUse atomic memory primitives.

Or Ostrovsky Concurrent Reference Counting 13/1/15 13 / 57

Motivation

ProblemLocking the whole object impedes performance.

SolutionLock the bare minimum needed.

MethodUse atomic memory primitives.

Or Ostrovsky Concurrent Reference Counting 13/1/15 13 / 57

The same algorithm, but with a twist - writing

Algorithm 3 Eager reference counting with CompareAndSwap - write1: Write(src, i, ref)2: if ref 6= null3: AtomicIncrement(&rc(ref)) /*rc=reference counter*/4: loop5: old ← src[i]6: if CompareAndSet(&src[i], old, ref)7: deleteReference(old)8: return9:

10: deleteReference(ref)11: if ref 6= null12: AtomicDecrement(&rc(ref))13: if rc(ref) = 014: for each fld in Pointers(ref)15: deleteReference(*fld)16: free(ref)

Or Ostrovsky Concurrent Reference Counting 13/1/15 14 / 57

The same algorithm, but with a twist

Algorithm 4 Eager reference counting with CompareAndSwap - reading

1: Read(src, i, ref)2: tgt ← src[i]3: AtomicIncrement(&rc(tgt))4: return tgt

Or Ostrovsky Concurrent Reference Counting 13/1/15 15 / 57

The same algorithm, but with a twist

Algorithm 5 Eager reference counting with CompareAndSwap - reading

1: Read(src, i, ref)2: tgt ← src[i]

free(tgt)3: AtomicIncrement(&rc(tgt))4: return tgt

Or Ostrovsky Concurrent Reference Counting 13/1/15 15 / 57

The same algorithm, but with a twist

Algorithm 6 Eager reference counting with CompareAndSwap2

1: Read(src, i, ref)2: loop3: tgt ← src[i]4: if tgt = null5: return null6: rc ← rc(tgt)7: if CompareAndSet2(&src[i], &rc(tgt), tgt,

rc, tgt, rc+1)8: return tgt

Or Ostrovsky Concurrent Reference Counting 13/1/15 16 / 57

Analysis

Pro.Simple(ish)Better performance - block fields and not objects

Con.Not practical - no CompareAndSet2Performance issues:

I LocksI Spin locks are bad

Or Ostrovsky Concurrent Reference Counting 13/1/15 17 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 18 / 57

Motivation

ProblemHeavy write barrier

SolutionLet another thread do all of the accounting

MethodBuffer all the ref. counting operations

Or Ostrovsky Concurrent Reference Counting 13/1/15 19 / 57

Motivation

ProblemHeavy write barrier

SolutionLet another thread do all of the accounting

MethodBuffer all the ref. counting operations

Or Ostrovsky Concurrent Reference Counting 13/1/15 19 / 57

Motivation

ProblemHeavy write barrier

SolutionLet another thread do all of the accounting

MethodBuffer all the ref. counting operations

Or Ostrovsky Concurrent Reference Counting 13/1/15 19 / 57

Implementation

Each mutator logs it’s operations using a write barrier.Each cycle:

I Collect logs from each threadI Apply reference count updatesI Reclaim memory

Time is divided into epochs.Deferred ref. counting is used.

Or Ostrovsky Concurrent Reference Counting 13/1/15 20 / 57

The new write barrier

Algorithm 7 Concurrent buffered reference counting - write

1: shared epoch2: shared updatesBuffer[] /*one per epoch*/3:

4: Write(src, i, ref)5: if src = Roots6: src[i] ← ref7: else8: old ← AtomicExchange(&src[i], ref)9: log(old, ref)

10:

11: log(old, new)12: append(myUpdates, 〈old, new〉)

Or Ostrovsky Concurrent Reference Counting 13/1/15 21 / 57

Collect - get local logs

Algorithm 8 Concurrent buffered reference counting - collect

1: collect()2: myStackBuffer ← []3: for each local ref in myStacks4: append(myStackBuffer, 〈ref, ref〉)5: atomic6: append(updatesBuffer[e], myStackBuffer)7: atomic8: append(updatesBuffer[e], myUpdates)9: myUpdates ← []

10: e ← e + 1

Or Ostrovsky Concurrent Reference Counting 13/1/15 22 / 57

Collect - apply changes

Algorithm 8 Concurrent buffered reference counting - collect

11: me ← myProcessorId12: if me < MAX PROCESSORS13: schedule(collect, me+1)14: else15: for each 〈old, new〉 in updatesBuffer[epoch]16: addReference(new)17: for each 〈old, new〉 in updatesBuffer[epoch - 1]18: deleteReference(old)19: release(updatesBuffer[epoch - 1])20: epoch ← epoch + 1

Or Ostrovsky Concurrent Reference Counting 13/1/15 23 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 3

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 4

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 3

B 2

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 2

B 2

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 1

B 2

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Example

T1

T2

B

A

B

A 1

B 1

A A

T1

A A

T2

e-1

A A

T1

A A B

T2

e

B B

T1

A A

T2

e+1

Or Ostrovsky Concurrent Reference Counting 13/1/15 24 / 57

Analysis

Pro.Performance

I Thin write barrierI On the flyI Allows for an independent collector threadI Incorporates deferred ref. counting

Con.Circle handlingHigh memory requirementsLog each operation

Or Ostrovsky Concurrent Reference Counting 13/1/15 25 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference CountingCoalesced Reference CountingSliding View

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 26 / 57

Motivation

ProblemCan’t use single-threaded algorithms concurrently

SolutionCreate a snapshot of the heap

MethodCreate a sliding view

Or Ostrovsky Concurrent Reference Counting 13/1/15 27 / 57

Motivation

ProblemCan’t use single-threaded algorithms concurrently

SolutionCreate a snapshot of the heap

MethodCreate a sliding view

Or Ostrovsky Concurrent Reference Counting 13/1/15 27 / 57

Motivation

ProblemCan’t use single-threaded algorithms concurrently

SolutionCreate a snapshot of the heap

MethodCreate a sliding view

Or Ostrovsky Concurrent Reference Counting 13/1/15 27 / 57

Coalesced reference counting - motivation

An observation:src[i ]← o1 rc(o0)−−, rc(o1) + +src[i ]← o2 rc(o1)−−, rc(o2) + +

. . . . . .src[i ]← on rc(on−1)−−, rc(on) + +

Redundancy?

Or Ostrovsky Concurrent Reference Counting 13/1/15 28 / 57

Coalesced reference counting - solution

Method:I Write barrier: log “clean” objects and mark them as “dirty”.I At the end of each cycle: rc(log(ref ))−−, rc(ref ) + +

Uses a snapshot of the heap - provided by the logs.The increments require the mutator to stop.Implementation

I Add a pointer to the object headerI The pointer points to the current log entryI Clean objects: getLogPointer(obj) = null

Or Ostrovsky Concurrent Reference Counting 13/1/15 29 / 57

Example

Colletor’slog

A

B C

Or Ostrovsky Concurrent Reference Counting 13/1/15 30 / 57

Example

Colletor’slog

A

B C

Or Ostrovsky Concurrent Reference Counting 13/1/15 30 / 57

Example

Colletor’slog

A

B C

Or Ostrovsky Concurrent Reference Counting 13/1/15 30 / 57

Sliding View

Levanoni and Petrank 2001Take an incremental, concurrent “snapshots” of the heap

I Each mutator logs writes on clean objects.I The collector collects the logs on mutator at a timeI The collector cleans dirty objectsI When the collector needs a object current heap

F If it’s clean - use itF Else - use a local log

Or Ostrovsky Concurrent Reference Counting 13/1/15 31 / 57

Final Result

Sliding view - taken at [ts , te]

A spread “snapshot” - statet(obj) s.t. t ∈ [ts , te]

heap

timets te

Or Ostrovsky Concurrent Reference Counting 13/1/15 32 / 57

Snooping

Problem - premature reclaimsI ref might be reclaimed

viewk

threads

time

collect o1

o1 = ref

ts te

Solution - “snoop” itI Keep it in a special bufferI Use it as a root in the current cycle

Or Ostrovsky Concurrent Reference Counting 13/1/15 33 / 57

Other Problems

Global log pointersI A race is possibleI Solution: The race has no effect.

Clean-modify conflictsI The mutator changes the object while it’s being cleanedI Solution: Reinforce dirty state if needed

Or Ostrovsky Concurrent Reference Counting 13/1/15 34 / 57

Building the local logsAlgorithm 9 Write barrier

1: Write(src, i, ref)2: if src = Roots3: src[i] ← ref4: else5: if not dirty(src)6: log(src)7: src[i] ← ref8: snoop(ref)9:

10: log(ref)11: for each fld in Pointers(ref)12: if *fld 6= null13: add(logs[me], *fld)14: if not dirty(ref)15: entry ← add(logs[me], ref)16: logPointer(ref) ← entry17:

18: snoop(ref)19: if snoopFlag[me] && ref 6= null20: append(mySnoopedBuffer, ref)

Or Ostrovsky Concurrent Reference Counting 13/1/15 35 / 57

Collect them

Algorithm 10 Sliding view collection1: collectSlidingView()2: for each t in threads /*handshake 1*/3: suspend(t)4: snoopFlag[t] ← true5: transfer t’s buffers to updates6: resume(t)7: clean modified and young objects8: for each t in threads /*handshake 2*/9: suspend(t)

10: find modify-clean conflicts11: resume(t)12: reinforce dirty objects13: for each t in threads /*handshake 3*/14: suspend(t)15: resume(t)

Or Ostrovsky Concurrent Reference Counting 13/1/15 36 / 57

Use them

Algorithm 11 Read sliding view1: readSlidingView(entry)2: obj ← objFromLog(entry)3: if not dirty(obj)4: replica ← copy(obj) /*read the current state*/5: if dirty(obj)6: replica ← getLogPointer(obj)7: else8: replica ← getLogPointer(obj)9: return replica

Or Ostrovsky Concurrent Reference Counting 13/1/15 37 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B C

Snoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Example

Mutators’slog

Collector’slog

A

B CSnoopbuffer

Or Ostrovsky Concurrent Reference Counting 13/1/15 38 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle CollectionOverviewConceptsThe big picture

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 39 / 57

An Efficient On-the-Fly Cycle Collection

A “Big algorithm” - incorporates many techniquesI Mark & Sweep (Lecs. 2 & 10)I Generational GC (Lec. 5)I The Recycler (Lec. 3)I Coalesced reference countingI Sliding views

Relatively new - Paz et al. 2007We’ll handle it very carefullyNo full pseudocode

Or Ostrovsky Concurrent Reference Counting 13/1/15 40 / 57

Mark & Sweep

Mark all reachable objects and reclaim the rest.Algorithm:

I Trace memory from roots.I Mark reachable objects.I Release unmarked objects

Work - proportional to the number of live objectsSimpler version need a “fixed” heap

Or Ostrovsky Concurrent Reference Counting 13/1/15 41 / 57

Generational garbage collection

The weak generational hypothesis: most objects die youngYoung generation

I High mutation and death ratesI Use1 Mark & Sweep - trace only live objects

Old generationI Low mutation and death ratesI Use1 Reference counting - handle big live heaps

1For the current schemeOr Ostrovsky Concurrent Reference Counting 13/1/15 42 / 57

The Recycler

Proposed by Bacon & Rajan at 2001Reclaim unreachable circles using trial deletionAlgorithm:

I Build a set of candidatesI Decrement counts for each candidate (mark as gray)I Scan objects reachable from candidates with rc 6= 0

F Those items are marked blackF The rest are marked white

I Remove white objectsMany traversals are required - needs a “fixed” heap

Or Ostrovsky Concurrent Reference Counting 13/1/15 43 / 57

Pseudocode

Algorithm 12 Cycle collection

1: collectCycles()2: markCandidates()3: markLiveBlack()4: scan()5: collectWhite()6: processBuffers()

Or Ostrovsky Concurrent Reference Counting 13/1/15 44 / 57

The major scheme

Objects are created youngLog old objectsCollect logs from each thread (one at a time)Clean dirty objectsUpdate reference counts of old objectsM&S young objectsApply the Recycler on old objects

Or Ostrovsky Concurrent Reference Counting 13/1/15 45 / 57

Corner rounding & circle squaring

Inter-generational pointersI Mark & Sweep - old → youngI The Recycler - young → old

“Live” heapsI Mark & Sweep - See Lec. 10I The Recycler - Retracing the graph

Aging - correct the reference count to and from a young object

Or Ostrovsky Concurrent Reference Counting 13/1/15 46 / 57

Corner rounding & circle squaring

Inter-generational pointersI Mark & Sweep - old → youngI The Recycler - young → old

“Live” heapsI Mark & Sweep - See Lec. 10I The Recycler - Retracing the graph

Aging - correct the reference count to and from a young object

Or Ostrovsky Concurrent Reference Counting 13/1/15 46 / 57

Solutions

Inter-generational pointersI old → young - mark objects when processing logsI young → old - young objects are candidates for the Recycler

“Live” heaps - Use the sliding viewAging

I References from - increment using sliding windowI References to - are logged with the old objects

Or Ostrovsky Concurrent Reference Counting 13/1/15 47 / 57

Allocating objects

Algorithm 13 Object allocation

1: New()2: ref ← allocate()3: add(myYoungSet, ref)4: setDirty(ref)5: return ref

Or Ostrovsky Concurrent Reference Counting 13/1/15 48 / 57

Actual reference countingAlgorithm 14 Reference count updates

1: incrementNew(entry)2: replica ← readSlidingView(entry)3: for each fld in Pointers(replica)4: child ← *fld5: if child 6= null6: rc(child) ← rc(child) + 17: mark(child) /*for M&S*/8:

9: decrementOld(entry)10: for each fld in Pointer(entry)11: child ← *fld12: if child 6= null13: rc(child) ← rc(child) - 114: if rc(child) = 015: add(ztc, child)16:

17: processReferenceCounts()18: for each entry in updates19: decrementOld(entry)20: incrementNew(entry)

Or Ostrovsky Concurrent Reference Counting 13/1/15 49 / 57

The “main” method

Algorithm 15 Collection

1: collect()2: collectSlidingView()3: for each t in threads /*handshake 4*/4: suspend(t)5: scanStack(t)6: snoopFlag[t] ← false7: resume(t)8: processReferenceCounts()9: markNursery()

10: sweepNursery()11: sweepZCT()12: collectCycles()

Or Ostrovsky Concurrent Reference Counting 13/1/15 50 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D E G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G0 2 1 0 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G1 1 1 1 0 0 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G1 1 1 1 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G1 0 0 1 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G1 1 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Example

Mutators’slog

Collector’slog A

B D

E

G

C F

Roots

Snoopbuffer

A B C D E F G0 1 0

Or Ostrovsky Concurrent Reference Counting 13/1/15 51 / 57

Analysis

Pro.Uses single-threaded algorithmsPerformance

I All the advantages of buffered reference countingI Fewer reference count changes

Handles circles

Con.Very complexRelatively new

Or Ostrovsky Concurrent Reference Counting 13/1/15 52 / 57

Table of contents

1 Introduction

2 Simple Reference Counting

3 Buffered Reference Counting

4 Sliding View Reference Counting

5 An Efficient On-the-Fly Cycle Collection

6 Summery

Or Ostrovsky Concurrent Reference Counting 13/1/15 53 / 57

Discussion

Sliding view limitationsImprovements for the on the fly collectorCombine algorithms with reference countingWhat is reference counting good for?

Or Ostrovsky Concurrent Reference Counting 13/1/15 54 / 57

Overview

Simple reference counting - both flavorsBuffered reference counting - let another thread do the accountingCoalesced reference counting - know what to ignoreSliding view - take a snapshot of the heap while it’s movingOn-the-Fly cycle collection - Sliding view usage example

Or Ostrovsky Concurrent Reference Counting 13/1/15 55 / 57

Any questions?

Or Ostrovsky Concurrent Reference Counting 13/1/15 56 / 57

Any comments?

Or Ostrovsky Concurrent Reference Counting 13/1/15 57 / 57