Recolección de Basura (garbage collec*on)
Paradigmas de la Programación FaMAF-‐UNC 2016
basado en filminas de Michael O. Lam hFp://www.cs.umd.edu/~lam/cmsc330/
summer2012/
CMSC 330 2
atributos de la memoria • Persistencia (o lifePme) – el Pempo en que existe
• Ubicación (o allocaPon) – disponibilidad • Recuperación – cuando el sistema recupera la memoria para reusarla
• cuatro diferentes Ppos de memoria: – fija (o estáPca) – automáPca (o stack) – alojada (o heap) – persistente (o disco)
CMSC 330 3
clases de memoria • estáPca – una dirección fija en la memoria
– persistencia – Pene el life*me de la ejecución de un programa
– ubicación – la ubica el compilador para toda la ejecución
– recuperación – la recupera el sistema cuando termina el programa
• automáPca – en el stack – persistence – Pene el lifePme del método que usa esos datos
– ubicación – cuando se invoca el método – recuperación – cuando termina el método
CMSC 330 4
clases de memoria • alojada – en el heap
– persistencia – por el Pempo que se necesita – ubicación – el programador la ubica específicamente – recuperación – el programador o automáPcamente
• persistente – en el sistema de archivos – persistencia – a través de varias ejecuciones de un programa
– ubicación – el programa o el usuario, generalmente fuera de la ejecución del programa
– recuperación – cuando no se necesita más
CMSC 330 5
gesPón de memoria en C
• las variables locales viven en el stack – se alojan cuando se invoca la función, – se desalojan cuando la función retorna, – el espacio se recupera después de que la función retorna
• el espacio en el heap se aloja con malloc() – hay que liberarlo explícitamente con free() – gesPón de memoria manual
CMSC 330 6
errores en gesPón de memoria • olvidar liberar memoria (memory leak)
{ int *x = (int *) malloc(sizeof(int)); }
• retener un puntero a memoria que ha sido liberada (dangling pointer)
{ int *x = ...malloc(); free(x); *x = 5; /* oops! */ }
• liberar algo dos veces { int *x = ...malloc(); free(x); free(x); } • puede corromper las estructuras de datos de gesPón de memoria, porque el alojador de memoria manPene una lista de espacio disponible en el heap
CMSC 330 7
cómo evitar errores • no alojar memoria en el heap
– imprácPco – código confuso
• no liberar memoria – el sistema operaPvo la reclama al finalizar el programa
– la memoria es barata • usar un recolector de basura, que recicla memoria automáPcamente cuando se da cuenta de que no se puede acceder más – para C, e recolector conservador Boehm-‐Weiser
CMSC 330 8
gesPón de memoria en Ruby
• las variables locales viven en el stack – se reclama el espacio cuando el método retorna
• los objetos viven en el heap – se crea con la llamada Class.new
• los objetos nunca se liberan explícitamente – Ruby usa ges*ón de memoria automá*ca
• usa un recolector de basura para recuperar memoria
CMSC 330 9
gesPón de memoria en OCaml
• las variables locales viven en el stack • las tuples, clausuras y Ppos construídos viven en el heap
• la memoria se recupera con garbage collecPon
CMSC 330 10
gesPón de memoria en Java
• las variables locales viven en el stack – se alojan cuando se invoca al método – se desalojan cuando el método retorna
• el resto de datos viven en el heap – la memoria se aloja con new – nunca se desaloja explícitamente, se usa gesPón de memoria automáPca
CMSC 330 11
otro problema de memoria: fragmentación allocate(a); allocate(x); allocate(y); free(a); allocate(z); free(y); allocate(b);
⇒ no hay espacio conPguo para b
CMSC 330 12
objePvo de la recolección de basura • proceso para recuperar memoria (y también resolver problemas de fragmentación)
• necesitas saber dónde están alojado en la memoria todos los punteros de un programa. Si mueves los datos, simplemente cambias el puntero.
• Se hace sólo en algunos lenguajes (LISP, OCaml, Java, Prolog).
CMSC 330 13
Recolección de basura (Garbage Collec*on (GC))
• en cualquier punto durante la ejecución se pueden dividir los objetos en el heap en dos clases: – objetos vivos que se usarán más tarde en el programa – objetos muertos que no se van a usar más (basura)
• queremos recuperar la memoria de los objetos muertos
• objePvo: reducir memory leaks y evitar dangling pointers
CMSC 330 14
muchas técnicas de GC
• en la mayoría de lenguajes no se puede saber seguro qué objetos están realmente vivos o muertos
• se hace una aproximación conservadora: erramos por el lado de decidir que algo está vivo cuando ya no lo está, mejor que desalojar un objeto que será usado más adelante
CMSC 330 15
Conteo de referencias (reference coun*ng)
• técnica vieja (1960) • cada objeto Pene un conteo del número de punteros que Pene de otros objetos y del stack
• cuando el conteo llega a 0, el objeto se puede desalojar
• no maneja el problema de la fragmentación
CMSC 330 16
ejemplo de conteo de referencias
CMSC 330 17
Reference CounPng Example
CMSC 330 18
Reference CounPng Example
CMSC 330 19
Reference CounPng Example
CMSC 330 20
Reference CounPng Example
CMSC 330 21
Reference CounPng Example
CMSC 330 22
Reference CounPng Example
CMSC 330 23
ventajas y desventajas • ventaja: técnica incremental, con canPdad de trabajo
constante por escritura de memoria • desventajas:
– los decrementos cascadeados pueden ser caros – requiere memoria extra para el conteo de referencias – no puede recuperar ciclos, porque el conteo nunca llega a 0
CMSC 330 24
alcanzabilidad • un objeto es alcanzable si se puede acceder con algún puntero desde datos vivos
• políPca segura: borrar solamente objetos no alcanzables – un objeto no alcanzable no va a poder ser accedido de vuelta por el programa, es claramente basura
– un objeto alcanzable podría ser accedido en el futuro, podría ser basura pero no lo vamos a eliminar
CMSC 330 25
raíces (roots) • en un punto dado del programa, definimos que un objeto está vivo si se puede alcanzar desde el conjunto de raíces: – variables globales – variables locales de todos los métodos acPvos (en un acPvaPon record en el stack)
• a nivel máquina también consideramos los registros
• se siguen recursivamente los punteros del conjunto de raíces para determinar que datos son alcanzables
CMSC 330 26
Mark and Sweep GC
• sólo pueden estar vivos los objetos alcanzables desde el stack – cada tanto, se para todo y se hace GC:
• se marcan todos los objetos en el stack como vivos • se marcan recursivamente todos los objetos alcanzables desde uno vivo como vivos, hasta que no hay más objetos alcanzables
• se desalojan los objetos no vivos
• no trata el problema de la fragmentación
CMSC 330 27
ejemplo de Mark and Sweep stack
CMSC 330 28
ejemplo de Mark and Sweep stack
CMSC 330 29
ejemplo de Mark and Sweep stack
CMSC 330 30
ejemplo de Mark and Sweep stack
CMSC 330 31
ejemplo de Mark and Sweep stack
CMSC 330 32
ejemplo de Mark and Sweep stack
CMSC 330 33
ejemplo de Mark and Sweep stack
CMSC 330 34
ventajas y desventajas de Mark and Sweep
• ventajas: – No Pene problema con los ciclos – las escrituras a memoria no Penen ningún coste
• desventajas: – fragmentación, muchos sistemas mark-‐and-‐sweep incorporan una fase de compactación
– coste proporcional al tamaño del heap, la fase de sweep Pene que atravesar todo el heap
– no es adecuado para aplicaciones de Pempo real, porque para el sistema
CMSC 330 35
GC parar y copiar
• como mark and sweep, pero sólo toca objetos vivos – se divide el heap en partes iguales (semispaces) – sólo una de estas partes está acPva en un momento determinado
– en Pempo de GC se cambian los semispaces • se trazan los datos vivos desde el stack • se copian los datos vivos en el otro semispace • se declara muerto todo lo que hay en el semispace actual y se cambia al otro semispace
CMSC 330 36
ejemplo Stop and Copy stack
CMSC 330 37
ejemplo Stop and Copy stack
①
①
CMSC 330 38
ejemplo Stop and Copy stack
①
①
②
②
CMSC 330 39
ejemplo Stop and Copy stack
①
①
②
②
③
③
CMSC 330 40
ventajas y desventajas Stop and Copy
• ventajas: – sólo toca datos vivos – sin fragmentación; compactación automáPca y aumento de localidad
• desventajas: – requiere el doble de espacio de memoria – necesita “parar el mundo”
CMSC 330 41
The GeneraPonal Principle
Object lifetime increases ⇒
Mor
e ob
ject
s liv
e ⇒
“Young objects die quickly; old objects keep living”
CMSC 330 42
Using The GeneraPonal Principle • Some objects live longer
– For instance, there are typically some objects allocated at iniPalizaPon that live unPl the process exits.
• Some objects live shorter – For instance, loop variables don't last long at all.
• Between these two extremes are objects that live for the duraPon of some intermediate computaPon (the “lump”).
• Many applicaPons have this general shape. • Focus on the fact that a majority of objects "die young".
CMSC 330 43
GeneraPonal CollecPon • Long lived objects get copied over and over
– Idea: Have more than one semispace, divide into generaPons • Older generaPons collected less oren • Objects that survive many collecPons get pushed into older generaPons
• Need to track pointers from old to young generaPons to use as roots for young generaPon collecPon
• GC in Java 2 is based on this idea
CMSC 330 44
More Issues in GC
• Stopping the world is a big problem – Unpredictable performance
• Bad for real-‐Pme systems – Need to stop all threads
• Without a much more sophisPcated GC
CMSC 330 45
More Issues in GC
• Building a “one-‐size fits all” soluPon is hard – Impossible to be opPmal for all programs – So correctness and safety come first
CMSC 330 46
What Does GC Mean to You?
• Ideally, nothing! – It should make your life easier – And shouldn’t affect performance too much
• If GC becomes a problem, hard to solve – You can oren set parameters of the GC – You can modify your program
CMSC 330 47
GC Parameters
• Can resize the generaPons – How much to use iniPally, plus max growth
• Change the total heap size – In terms of an absolute measure – In terms of raPo of free/allocated data
• For server applicaPons, two common tweaks: – Make the total heap as big as possible – Make the young generaPon half the total heap
CMSC 330 48
Bad Ideas (Usually)
• Calling System.gc() – This is probably a bad idea – You have no idea what the GC will do – And it will take a while
• Managing memoria yourself – Object pools, free lists, object recycling – GC’s have been heavily tuned to be efficient
CMSC 330 49
Dealing with GC Problems • Best idea: Measure where your problems are coming from • For Java VM, try running with
– -‐verbose:gc – Prints out messages with staPsPcs when a GC occurs
• [GC 325407K-‐>83000K(776768K), 0.2300771 secs] • [GC 325816K-‐>83372K(776768K), 0.2454258 secs] • [Full GC 267628K-‐>83769K(776768K), 1.8479984 secs]
As a language designer...
• Don’t allow pointer types to mix with integer types – Makes liveness analysis much easier – Also helps with other types of analysis
• Less trouble with aliasing • Discourage top-‐level allocaPon
– Difficult or impossible to free top-‐level structures automaPcally
• Encourage Pght scoping – Easier to make GC decisions
CMSC 330
Top Related