Recolección)de)Basura) garbage&collecon...CMSC)330) 3 clases)de)memoria) • estáca...
Transcript of Recolección)de)Basura) garbage&collecon...CMSC)330) 3 clases)de)memoria) • estáca...
-
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