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 * **Marcado y barrido**
49 * Copia de semi-espacio
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 en un tipo
269 * Indica si una *palabra* debe ser escaneada (uniones)
270 * Indica si una palabra es un puntero
272 * Se pasa esa información al recolector al momento de pedir memoria
273 * Recolector original utiliza esa información
275 * Almacena un puntero a la información al final del bloque
276 * Utiliza la información para escanear solo palabras que son punteros (con
277 seguridad o potencialmente)
279 Optimizaciones y Otras Mejoras Menores
280 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281 * Mejora del factor de ocupación del *heap*
282 * Caché de consultas críticas para acelerar cuellos de botella
283 * Reestructuración, modularización, simplificación y limpieza del código
284 * Pre-asignación de memoria
285 * Optimizaciones algorítmicas sobre búsquedas frecuentes
286 * Registro de pedidos de memoria y recolecciones realizadas
290 * Configurable en *tiempo de arranque*
291 * Vía variable de entorno (``D_GC_OPTS``)
292 * Viejas opciones convertidas
301 * ``malloc_stats_file``
302 * ``collect_stats_file``
311 ==============================================================================
314 --------------------------------------------------
318 * Múltiples corridas (20-50)
320 * Minimizar error en la medición
321 * Resultados expresados en función de:
328 * Minimizar variación entre corridas
338 * Ejercitar aspectos puntuales
339 * No realizan una tarea útil
342 * Programas pequeños - *Olden Benchmark* (5)
344 * Relativamente pequeños (400-1000 *SLOC*)
345 * Realizan una tarea útil
346 * Manipulan mucho listas y árboles asignando mucha memoria
347 * No son ideales para probar un *GC*
349 * Programas reales - **Dil** (1)
351 * Compilador de D escrito en D
352 * Grande y complejo (32K+ *SLOC*, 86 módulos, 300+ *clases*)
353 * Programado sin (limitaciones ni ventajas del) *GC* en mente
354 * Manipulación de *strings*, arreglos dinámicos y asociativos
358 * Tiempo total de ejecución
359 * Tiempo máximo de *stop-the-world*
360 * Tiempo máximo de pausa real
361 * Cantidad máxima de memoria utilizada
362 * Cantidad total de recolecciones realizadas
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
379 Tiempo Total de Ejecución
380 ~~~~~~~~~~~~~~~~~~~~~~~~~
381 .. image:: img/norm-hist-time.pdf
384 Cantidad total de recolecciones realizadas
385 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386 .. image:: img/norm-hist-ncol.pdf
389 Cantidad máxima de memoria utilizada
390 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
391 .. image:: img/norm-hist-mem.pdf
397 ==============================================================================
400 --------------------------------------------------
406 Minimizar tiempo de pausa para programas reales
408 Tiempo de pausa de Dil:
410 * *Stop-the-world* **160 veces menor** (1.66s → 0.01s)
411 * Pausa real **40 veces menor** (1.7s → 0.045s)
413 * Objetivo secundario
415 No empeorar mucho el recolector actual en ningún aspecto
417 Utilización de memoria de Dil:
419 **50% mayor** (mucho *overhead* por marcado preciso)
423 Tiempo total de ejecución de Dil:
425 Casi **3 veces menor** (55s → 20s)
427 Problemas, Limitaciones y Puntos Pendientes
428 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
429 * Explosión de uso de memoria con *eager allocation*
430 * Eficiencia del marcado preciso
431 * Mejorar predicción de *early collection*
432 * Experimentar con ``clone(2)``
434 Trabajos Relacionados
435 ~~~~~~~~~~~~~~~~~~~~~
436 * *Memory Management in the D Programming Language*
438 Vladimir Panteleev. Proyecto de licenciatura, Universitatea Tehnică
441 * *Integrate Precise Heap Scanning Into the GC*
443 David Simcha (GC + diseño) y Vincent Lang (compilador). No formal, *bug
446 * *Non-intrusive Cloning Garbage Collection with Stock Operating System Support*
448 Gustavo Rodriguez-Rivera y Vince Russo. Software Practiceand Experience
449 Volumen 27, Número 8. Agosto 1997.
453 * Organización de memoria
456 * Concurrencia → *Lock* **global**
468 .. vim: set et sw=4 sts=4 spell spelllang=es :