Garbage Collection Basics

Similar documents
Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

Reference Counting. Reference counting: a way to know whether a record has other users

Reference Counting. Reference counting: a way to know whether a record has other users

Programming Languages: Application and Interpretation

Programming Languages: Application and Interpretation

Runtime. The optimized program is ready to run What sorts of facilities are available at runtime

Acknowledgements These slides are based on Kathryn McKinley s slides on garbage collection as well as E Christopher Lewis s slides

Garbage Collection. Steven R. Bagley

CS61, Fall 2012 Section 2 Notes

Scheme as implemented by Racket

Lecture 13: Garbage Collection

Managed runtimes & garbage collection. CSE 6341 Some slides by Kathryn McKinley

Tick: Concurrent GC in Apache Harmony

Today. Dynamic Memory Allocation: Advanced Concepts. Explicit Free Lists. Keeping Track of Free Blocks. Allocating From Explicit Free Lists

Algorithms for Dynamic Memory Management (236780) Lecture 4. Lecturer: Erez Petrank

Managed runtimes & garbage collection

Dynamic Memory Allocation: Advanced Concepts

Simple Garbage Collection and Fast Allocation Andrew W. Appel

CS577 Modern Language Processors. Spring 2018 Lecture Garbage Collection

Garbage Collection. Hwansoo Han

CS 153 Design of Operating Systems

Harmony GC Source Code

One-Slide Summary. Lecture Outine. Automatic Memory Management #1. Why Automatic Memory Management? Garbage Collection.

Dynamic Data Structures (II)

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Garbage Collection Algorithms. Ganesh Bikshandi

Lecture 15 Garbage Collection

Dynamic Memory Alloca/on: Advanced Concepts

Structure of Programming Languages Lecture 10

Precise Garbage Collection for C. Jon Rafkind * Adam Wick + John Regehr * Matthew Flatt *

CS 345. Garbage Collection. Vitaly Shmatikov. slide 1

CMSC 330: Organization of Programming Languages

Memory Management. Memory Management... Memory Management... Interface to Dynamic allocation

Lecture Notes on Garbage Collection

Programming Language Implementation

Lecture 15 Advanced Garbage Collection

Scope, Functions, and Storage Management

Review. Partitioning: Divide heap, use different strategies per heap Generational GC: Partition by age Most objects die young

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

Mark-Sweep and Mark-Compact GC

CS 360 Programming Languages Day 14 Closure Idioms

CS558 Programming Languages

CMSC 330: Organization of Programming Languages

Automatic Garbage Collection

Internal Fragmentation

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Dynamic Memory Allocation

Run-time Environments -Part 3

Process s Address Space. Dynamic Memory. Backing the Heap. Dynamic memory allocation 3/29/2013. When a process starts the heap is empty

Qualifying Exam in Programming Languages and Compilers

Run-time Environments - 3

Automatic Memory Management

A.Arpaci-Dusseau. Mapping from logical address space to physical address space. CS 537:Operating Systems lecture12.fm.2

This class is about understanding how programs work

Dynamic Memory Allocation

CMSC 330: Organization of Programming Languages. Memory Management and Garbage Collection

CS842: Automatic Memory Management and Garbage Collection. Mark and sweep

ACM Trivia Bowl. Thursday April 3 rd (two days from now) 7pm OLS 001 Snacks and drinks provided All are welcome! I will be there.

CS 241 Honors Memory

Dynamic Memory Allocation: Advanced Concepts

Implementation Garbage Collection

CMSC 341 Lecture 7 Lists

Compiler Construction D7011E

Compilers. 8. Run-time Support. Laszlo Böszörmenyi Compilers Run-time - 1

Shenandoah: An ultra-low pause time garbage collector for OpenJDK. Christine Flood Principal Software Engineer Red Hat

Dynamic Memory Allocation II October 22, 2008

6.172 Performance Engineering of Software Systems Spring Lecture 9. P after. Figure 1: A diagram of the stack (Image by MIT OpenCourseWare.

Shenandoah: An ultra-low pause time garbage collector for OpenJDK. Christine Flood Roman Kennke Principal Software Engineers Red Hat

Dynamic Memory Allocation: Advanced Concepts

Memory Allocation III CSE 351 Spring (original source unknown)

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Book keeping. Will post HW5 tonight. OK to work in pairs. Midterm review next Wednesday

What goes inside when you declare a variable?

Towards Lean 4: Sebastian Ullrich 1, Leonardo de Moura 2.

Robust Memory Management Schemes

A new Mono GC. Paolo Molaro October 25, 2006

Heap Compression for Memory-Constrained Java

Agenda. CSE P 501 Compilers. Java Implementation Overview. JVM Architecture. JVM Runtime Data Areas (1) JVM Data Types. CSE P 501 Su04 T-1

Garbage Collection. CS 351: Systems Programming Michael Saelee

Implementing Subprograms

Garbage Collection. Akim D le, Etienne Renault, Roland Levillain. May 15, CCMP2 Garbage Collection May 15, / 35

CS 360 Programming Languages Interpreters

CA341 - Comparative Programming Languages

Garbage Collection. Weiyuan Li

Announcements. Scope, Function Calls and Storage Management. Block Structured Languages. Topics. Examples. Simplified Machine Model.

HOT-Compilation: Garbage Collection

Sustainable Memory Use Allocation & (Implicit) Deallocation (mostly in Java)

Lecture 8 Dynamic Memory Allocation


the gamedesigninitiative at cornell university Lecture 9 Memory Management

Glacier: A Garbage Collection Simulation System

YOUR NAME PLEASE: *** SOLUTIONS ***

CSE P 501 Compilers. Memory Management and Garbage Collec<on Hal Perkins Winter UW CSE P 501 Winter 2016 W-1

Compiler Construction

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Opera&ng Systems CMPSCI 377 Garbage Collec&on. Emery Berger and Mark Corner University of Massachuse9s Amherst

Binghamton University Dynamic Memory Alloca/on

Memory Management: The Details

INF 102 CONCEPTS OF PROG. LANGS FUNCTIONAL COMPOSITION. Instructors: James Jones Copyright Instructors.

Transcription:

Garbage Collection Basics 1

Freeing memory is a pain Need to decide on a protocol (who frees what when?) Pollutes interfaces Errors hard to track down Remember 211 / 213?... but lets try an example anyway (fre isn't hot until it burns me)

Freeing memory is a pain void removesome (node *head) { node *current; while (current) { if (shouldremove(current->payload)) { current->prev->next = current->next; current->next->prev = current->prev; current = current->next; We're not freeing anything; leaking like a sieve.

Freeing memory is a pain void removesome (node *head) { node *current; while (current) { if (shouldremove(current->payload)) { free(current->payload); current->prev->next = current->next; current->next->prev = current->prev; current = current->next; Better, but still leaking.

Freeing memory is a pain void removesome (node *head) { node *current, *next; while (current) { if (shouldremove(current->payload)) { free(current->payload); free(current); current->prev->next = current->next; current->next->prev = current->prev; current = current->next; Now we're freeing too soon.

Freeing memory is a pain void removesome (node *head) { node *current, *next; while (current) { if (shouldremove(current->payload)) { free(current->payload); current->prev->next = current->next; current->next->prev = current->prev; free(current); current = current->next; Still too soon. 111

Freeing memory is a pain void removesome (node *head) { node *current, *next; while (current) { next = current->next; if (shouldremove(current->payload)) { free(current->payload); current->prev->next = next; next->prev = current->prev; free(current); current = next; Finally got it right. I think... But what a mess! Logic and memory management tangled up! 11

Automatic storage management PLs come with their own implementation of allocation; why not freeing too? When can we free an object? When we can guarantee that it won t be used again in the computation (ground truth)... when it isn t reachable (conservative approximation); this is garbage collection 11

Garbage Collection Garbage collection: a way to know whether a record is live i.e., accessible Values on the stack & in registers are live (the roots) A record referenced by a live record is also live A program can only possibly use live records, because there is no way to get to other records A garbage collector frees all records that are not live Allocate until we run out of memory, then run a garbage collector to get more space 11

Time to write a garbage collector Two new languages: #lang plai/gc2/mutator for writing progams to be collected, and #lang plai/gc2/collector for writing collectors Collector interface, see section 2 of the PLAI docs (search for init-allocator) 1

Rules of the game All values are allocated (we have no type information!) Atomic values (ft in one cell in memory) include numbers (a lie), symbols (a less bad lie), booleans, and the empty list Compound values (require multiple cells in memory) include pairs and closures

A non-collecting collector Put the allocation pointer at address 0 Allocate all constants in the heap, tag them with 'flat Allocate all pairs in the heap, tag them with 'pair Allocate all closures in the heap, tag them with 'proc 1

A non-collecting collector #lang plai/gc2/collector (define (init-allocator) (heap-set! 0 1)) (define (alloc n) (define addr (heap-ref 0)) (unless (<= (+ addr n) (heap-size)) (error 'allocator "out of memory")) (heap-set! 0 (+ addr n)) addr)

A non-collecting collector, cont d (define (gc:flat? addr) (equal? (heap-ref addr) 'flat)) (define (gc:alloc-flat x) (define addr (alloc 2)) (heap-set! addr 'flat) (heap-set! (+ addr 1) x) addr) (define (gc:deref addr) (unless (equal? (heap-ref addr) 'flat) (error 'gc:deref "not a flat @ ~a" addr)) (heap-ref (+ addr 1)))

A non-collecting collector, cont d (define (gc:cons f r) (define addr (alloc 3)) (heap-set! addr 'cons) (heap-set! (+ addr 1) (read-root f)) (heap-set! (+ addr 2) (read-root r)) addr) (define (gc:cons? addr) (equal? (heap-ref addr) 'cons))

A non-collecting collector, cont d (define (gc:first addr) (check-pair addr) (heap-ref (+ addr 1))) (define (gc:rest p) (check-pair p) (heap-ref (+ p 2))) (define (check-pair addr) (unless (equal? (heap-ref addr) 'cons) (error 'check-pair "not a pair @ ~a" addr)))

A non-collecting collector, cont d (define (gc:set-first! addr v) (check-pair addr) (heap-set! (+ addr 1) v)) (define (gc:set-rest! addr v) (check-pair addr) (heap-set! (+ addr 2) v))

A non-collecting collector, cont d (define (gc:closure code-pointer free-vars) (define addr (alloc (+ 2 (length free-vars)))) (heap-set! addr 'proc) (heap-set! (+ addr 1) code-pointer) (for ([i (in-range 0 (length free-vars))] [v (in-list free-vars)]) (heap-set! (+ addr 2 i) (read-root v))) addr)

A non-collecting collector, cont d (define (gc:closure? addr) (equal? (heap-ref addr) 'proc)) (define (gc:closure-code-ptr addr) (unless (gc:closure? addr) (error "not a closure @ ~a" addr)) (heap-ref (+ addr 1))) (define (gc:closure-env-ref addr i) (unless (gc:closure? addr) (error "not a closure @ ~a" addr)) (heap-ref (+ addr 2 i)))

Testing a collector We can use with-heap to test a collector. The expression (with-heap h-expr body-exprs...) expects h-expr to evaluate to a vector and then it uses that vector as the memory that heap-ref and heap-set! refer to while evaluating the body-exprs.

Testing our non-collecting collector (let ([h (vector 'x 'x 'x 'x 'x)]) (test (with-heap h (init-allocator) (gc:alloc-flat #f) h) (vector 3 'flat #f 'x 'x)))

Testing our non-collecting collector (let ([h (vector 'x 'x 'x 'x 'x 'x 'x 'x 'x)]) (test (with-heap h (init-allocator) (gc:cons (simple-root (gc:alloc-flat #f)) (simple-root (gc:alloc-flat #t))) h) (vector 8 'flat #f 'flat #t 'cons 1 3 'x))) ; (Of course, this is not enough testing.) 1

Testing with mutator programs #lang plai/gc2/mutator (allocator-setup "mygc.rkt" 200) ; heap size (cons 1 (cons 2 (cons 3 empty)))

We can also use random testing to generate mutators. A plai library generates code that makes interesting heap structures (randomly), and then makes up a traversal of them. The next three slides give three example random mutators and the calls into the library that generated them.

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "mygc.rkt" #:gc2? #t) #lang plai/gc2/mutator (allocator-setup "mygc.rkt" 200) (define (build-one) (let* ((x0 'x) (x1 (cons #f #f)) (x2 (cons x1 #f)) (x3 (lambda (x) (if (= x 0) x0 (if (= x 1) x2 (if (= x 2) x2 (if (= x 3) x2 (if (= x 4) x1 x2))))))) (x4 (lambda (x) (if (= x 0) x1 (if (= x 1) x0 (if (= x 2) x1 (if (= x 3) x2 (if (= x 4) x1 (if (= x 5) x2 (if (= x 6) x3 (if (= x 7) x0 (if (= x 8) x0 x3))))))))))) (x5 (lambda (x) (if (= x 0) x3 x0))) (x6 (lambda (x) x1))) (set-first! x1 x4) (set-rest! x1 x2) (set-rest! x2 x5) x4)) (define (traverse-one x4) (symbol=? 'x ((rest ((first ((first ((first (x4 4)) 0)) 0)) 3)) 1))) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200)

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "mygc.rkt" #:gc2? #t) #lang plai/gc2/mutator (allocator-setup "mygc.rkt" 200) (define (build-one) (let* ((x0 0)) x0)) (define (traverse-one x0) (= 0 x0)) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200)

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "mygc.rkt" #:gc2? #t) #lang plai/gc2/mutator (allocator-setup "mygc.rkt" 200) (define (build-one) (let* ((x0 empty) (x1 (lambda (x) (if (= x 0) x0 (if (= x 1) x0 (if (= x 2) x0 (if (= x 3) x0 (if (= x 4) x0 (if (= x 5) x0 (if (= x 6) x0 (if (= x 7) x0 x0))))))))))) x1)) (define (traverse-one x1) (empty? (x1 0))) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200)