2 ==========================
3 Recolección de Basura en D
4 ==========================
6 :Autor: Leandro Lucarella
12 ==============================================================================
15 --------------------------------------------------
19 * Recolección de basura
20 * Lenguaje de programación D
21 * Utilidad → Software Libre → Contribución
25 --------------------------------------------------
31 * Administración automática de memoria
35 * Simplificar interfaces
36 * Mejorar eficiencia (**!**)
37 * Evitar errores de memoria
47 * Conteo de referencias
48 * Copia de semi-espacio
49 * **Marcado y barrido**
53 \multiinclude[format=pdf,graphics={height=4.5cm}]{img/mark-sweep}
55 .. dummy: para que ande bien el raw de arriba
59 * Medio siglo de investigación y desarrollo (3000+ publicaciones)
62 * ↓ Tiempo total de ejecución
63 * ↓ Cantidad de recolecciones
64 * ↓ Tiempo de recolección
65 * ↓ **Tiempo (máximo) de pausa**
71 * Organización de memoria
76 El Lenguaje de Programación D
77 --------------------------------------------------
79 Características Generales
80 ~~~~~~~~~~~~~~~~~~~~~~~~~
83 * Sistema de tipos estático
88 * Programación de bajo nivel (*system-programming*) ← C/C++
95 → Conservativo + Manipulación de *root set*
97 * Programación de alto nivel ← Python/Ruby/Perl
102 → Punteros interiores
104 * Orientación a objetos ← Java
112 Recolector de Basura de D
113 ==============================================================================
115 Implementación Actual
116 --------------------------------------------------
118 Organización del Heap
119 ~~~~~~~~~~~~~~~~~~~~~
120 *Heap* → *Pools* → Páginas → Bloques + Listas de libres
122 .. image:: img/heap.pdf
127 * Tamaño fijo (por página)
131 * Más de 4096 (una página)
134 * Múltiplo de páginas: 4096, 8192, ...
135 * En páginas contiguas (y mismo *pool*)
137 * Indicadores (*bit sets* en *pool*)
158 * Con una pizca de *precisión* (``NO_SCAN``)
162 * Durante el marcado, en teoría
166 * Muy propenso a extender el tiempo de *stop-the-world* en la práctica
169 Lo Bueno, lo Malo y lo Feo
170 --------------------------------------------------
175 * Organización del *heap* (*two-level allocation*)
176 * Marcado iterativo (!\ *overflow*)
177 * *Bit set* para indicadores (caché)
185 * ↓ Configurabilidad (*no silver bullet*)
186 * ↓ Precisión (información de tipos) → Memoria inmortal
187 * ↓ Concurrencia → Grandes pausas
188 * ↓ Control sobre el factor de ocupación del *heap* → casos patológicos
192 * El código (complejo, intrincado, duplicado, poco documentado) → Difícil de
193 mantener, modificar y mejorar
197 Modificaciones Propuestas
198 ==============================================================================
201 --------------------------------------------------
205 * Hijo *nace* con una *fotografía* de la memoria del padre
206 * Aisla modificaciones en la memoria de padre e hijo
207 * Minimiza copia efectiva de memoria (*COW*)
208 * Comienza con un solo hilo (el que llamó a ``fork(2)``)
213 * Basado en el trabajo de Gustavo Rodriguez-Rivera y Vince Russo (*Non-intrusive
214 Cloning Garbage Collector with Stock Operating System Support*)
215 * Minimiza tiempo de pausa realizando fase de marcado **concurrente** vía
217 * Proceso padre sigue corriendo el programa
218 * Proceso hijo realiza fase de marcado
219 * Se comunican resultados vía memoria compartida
220 * Sincronización mínima (``fork(2)`` + ``waitpid(2)``)
224 * Hilo que disparó la recolección bloqueado hasta fin de recolección completa
225 (marcado concurrente inclusive)
226 * Otros hilos potencialmente bloqueados durante toda la recolección también
229 → Tiempo de pausa en la práctica ~= tiempo total de recolección
233 * Crea un nuevo *pool* de memoria antes de lanzar el marcado concurrente
234 * Devuelve memoria del nuevo *pool* al programa mientras termina el marcado
236 * Permite al programa (**todos** sus hilos) seguir trabajando mientras se
237 realiza el marcado concurrente
242 ↓ Tiempo de pausa real
246 * Dispara una recolección *preventiva* antes de que se agote la memoria
247 * Permite al programa (**todos** sus hilos) seguir trabajando mientras la
248 recolección *preventiva* está en progreso
249 * Si se agota la memoria antes de que la recolección *preventiva* finalice, se
251 * Combinable con *eager allocation* para evitar bloquear
252 * Pueden realizarse más recolecciones de las necesarias
255 ↑ Consumo de procesador (potencialmente)
257 ↓ Tiempo de pausa real (no garantizado)
261 --------------------------------------------------
265 Adaptación del trabajo de Vincent Lang y David Simcha:
267 * Compilador genera información sobre ubicación de los punteros para cada tipo
270 * Indica si una *palabra* debe ser escaneada (uniones)
271 * Indica si una palabra es un puntero
273 * Se pasa esa información al recolector al momento de pedir memoria
274 * Recolector original utiliza esa información
276 * Almacena un puntero a la información al final del bloque
277 * Utiliza la información para escanear solo palabras que son punteros (con
278 seguridad o potencialmente)
280 Optimizaciones y Otras Mejoras Menores
281 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282 * Mejora del factor de ocupación del *heap*
283 * Caché de consultas críticas para acelerar cuellos de botella
284 * Reestructuración, modularización, simplificación y limpieza del código
285 * Pre-asignación de memoria
286 * Optimizaciones algorítmicas sobre búsquedas frecuentes
287 * Registro de pedidos de memoria y recolecciones realizadas
291 * Configurable en *tiempo de arranque*
292 * Vía variable de entorno (``D_GC_OPTS``)
293 * Viejas opciones convertidas
302 * ``malloc_stats_file``
303 * ``collect_stats_file``
312 ==============================================================================
315 --------------------------------------------------
319 * Múltiples corridas (20-50)
321 * Minimizar error en la medición
322 * Resultados expresados en función de:
329 * Minimizar variación entre corridas
339 * Ejercitar aspectos puntuales
340 * No realizan una tarea útil
343 * Programas pequeños - *Olden Benchmark* (5)
345 * Relativamente pequeños (400-1000 *SLOC*)
346 * Realizan una tarea útil
347 * Manipulan mucho listas y árboles asignando mucha memoria
348 * No son ideales para probar un *GC*
350 * Programas reales - **Dil** (1)
352 * Compilador de D escrito en D
353 * Grande y complejo (32K+ *SLOC*, 86 módulos, 300+ *clases*)
354 * Programado sin (limitaciones ni ventajas del) *GC* en mente
355 * Manipulación de *strings*, arreglos dinámicos y asociativos
359 * Tiempo total de ejecución
360 * Tiempo máximo de *stop-the-world*
361 * Tiempo máximo de pausa real
362 * Cantidad máxima de memoria utilizada
366 --------------------------------------------------
368 Tiempo Máximo de Stop-The-World
369 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
370 .. image:: img/norm-hist-stw.pdf
373 Tiempo Máximo de Pausa Real
374 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
375 .. image:: img/norm-hist-pause.pdf
378 Cantidad Máxima de Memoria Utilizada
379 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
380 .. image:: img/norm-hist-mem.pdf
383 Tiempo Total de Ejecución
384 ~~~~~~~~~~~~~~~~~~~~~~~~~
385 .. image:: img/norm-hist-time.pdf
391 ==============================================================================
394 --------------------------------------------------
400 Minimizar tiempo de pausa para programas reales
402 Tiempo de pausa de Dil:
404 * *Stop-the-world* **160 veces menor** (1.66s → 0.01s)
405 * Pausa real **40 veces menor** (1.7s → 0.045s)
407 * Objetivo secundario
409 No empeorar mucho el recolector actual en ningún aspecto
411 Utilización de memoria de Dil:
413 **50% mayor** (mucho *overhead* por marcado preciso)
417 Tiempo total de ejecución de Dil:
419 Casi **3 veces menor** (55s → 20s)
421 Problemas, Limitaciones y Puntos Pendientes
422 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
423 * Explosión de uso de memoria con *eager allocation*
424 * Eficiencia del marcado preciso
425 * Mejorar predicción de *early collection*
426 * Experimentar con ``clone(2)``
428 Trabajos Relacionados
429 ~~~~~~~~~~~~~~~~~~~~~
430 * *Memory Management in the D Programming Language*
432 Vladimir Panteleev. Proyecto de licenciatura, Universitatea Tehnică
435 * *Integrate Precise Heap Scanning Into the GC*
437 David Simcha (GC + diseño) y Vincent Lang (compilador). No formal, *bug
440 * *Non-intrusive Cloning Garbage Collection with Stock Operating System Support*
442 Gustavo Rodriguez-Rivera y Vince Russo. Software Practiceand Experience
443 Volumen 27, Número 8. Agosto 1997.
447 * Organización de memoria
450 * Concurrencia → *Lock* **global**
462 .. vim: set et sw=4 sts=4 spell spelllang=es :