hay necesidad de que la información de tipos sea parte del *root set*). Esto
causa que por cada recolección, se tenga que visitar bastante más memoria y,
lo que es probablemente peor, que aumente la probabilidad de encontrar
- *falsos punteros*, dado que este área de memoria se marca siempre de forma
+ *falsos positivos*, dado que este área de memoria se marca siempre de forma
conservativa.
Finalmente, en el cuadro :vref:`t:con-binsize` también se puede observar un
y ``dil``).
Este problema no solo afecta al consumo de memoria, además genera un efecto
- dominó por el incremento de la probabilidad de tener *falsos punteros*
+ dominó por el incremento de la probabilidad de tener *falsos positivos*
y perjudica al tiempo total de ejecución por empeorar la localidad de
referencia del caché y por hacer que se prolongue la recolección de basura
por tener que marcar y barrer más memoria.
El control sobre la alineación de memoria es otra complicación sobre el
recolector de basura, incluso aunque éste sea conservativo. Dado que tratar la
memoria de forma conservativa byte a byte sería impracticable (tanto por la
-cantidad de falsos positivos que esto provocaría como por el impacto en el
+cantidad de *falsos positivos* que esto provocaría como por el impacto en el
rendimiento por el exceso de posibles punteros a revisar, además de lo
ineficiente que es operar sobre memoria no alineada), en general el recolector
asume que el usuario nunca va a tener la única referencia a un objeto en una
de marcado (que es iterativa y realiza varias pasadas sobre **todo** el
*heap*, incluyendo las celdas libres) no visite las celdas libres perdiendo
tiempo sin sentido y potencialmente manteniendo *vivas* celdas que en
-realidad son *basura* (falsos positivos)::
+realidad son *basura* (*falsos positivos*)::
function mark_free_lists() is
foreach free_list in heap
Finalización
^^^^^^^^^^^^
El recolector actual no garantiza la finalización de objetos. En particular
-los objetos no son finalizados (es decir, no se llama a sus destructores)
-si aún alcanzables desde el *root set* cuando el programa termina. Cabe
-destacar que esto puede darse porque hay una referencia real desde el *root
-set* (en cuyo caso queda bajo el control del usuario) pero también, dado que
-el *root set* se visita de forma conservativa, se puede deber a un falso
-positivo, en cuyo caso la omisión de la finalización queda por completo fuera
-del control del usuario (y lo que es aún peor, el usuario no puede ser
-siquiera notificado de esta anomalía).
+los objetos no son finalizados (es decir, no se llama a sus destructores) si
+aún alcanzables desde el *root set* cuando el programa termina. Cabe destacar
+que esto puede darse porque hay una referencia real desde el *root set* (en
+cuyo caso queda bajo el control del usuario) pero también, dado que el *root
+set* se visita de forma conservativa, se puede deber a un *falso positivo*, en
+cuyo caso la omisión de la finalización queda por completo fuera del control
+del usuario (y lo que es aún peor, el usuario no puede ser siquiera notificado
+de esta anomalía).
Si bien la especificación de D_ no requiere esta capacidad (de hecho,
rigurosamente hablando la especificación de D_ no garantiza la finalización de
:ref:`concurrente <gc_concurrent>` y parcialmente más :ref:`preciso
<gc_conserv>`. Estas dos mejoras solamente alcanzarían para mejorar de forma
notable el tiempo de pausa en las recolecciones y la cantidad de memoria
-retenida debido a falsos positivos.
+retenida debido a *falsos positivos*.
Más adelante veremos detalles sobre algunos de estos aspectos y sobre algunos
algoritmos particulares que permiten hacer concurrente al recolector actual.
Cabe aclarar que esta es una definición conceptual, asumiendo que el programa
siempre limpia una dirección de memoria almacenada en el *root set* o una
celda del *heap* cuando la celda a la que apunta no va a ser utilizada
-nuevamente. Esto no es siempre cierto y los falsos positivos que esto produce
-se conoce como un tipo de pérdida de memoria (que es posible incluso al
-utilizar un recolector de basura) llamada pérdida de memoria *lógica*. Esto
+nuevamente. Esto no es siempre cierto y los *falsos positivos* que esto
+produce se conoce como un tipo de pérdida de memoria (que es posible incluso
+al utilizar un recolector de basura) llamada pérdida de memoria *lógica*. Esto
puede no ser evitable (incluso cuando el programador no cometa errores) en
lenguajes de programación que requieran un recolector de basura conservativo.
Basura = V - Live \thickspace set
-Esto es, efectivamente, una partición del *heap* (ver figura
+El *Live set* y la *Basura* conforman una partición del *heap* (ver figura
:vref:`fig:gc-heap-parts`).
con la dirección de memoria en la que está almacenada esa celda *basura*
[#gcflasepos]_. Además los recolectores puramente conservativos no puede mover
celdas (ver :ref:`gc_moving`), porque no pueden arriesgarse a actualizar los
-punteros por el riesgo que existe de que sean falsos positivos.
+punteros por el riesgo que existe de que sean *falsos positivos*.
.. [#gcflasepos] Esto es lo que se conoce como un *falso positivo*, algo que
aparenta ser un puntero pero en realidad no lo es.
Este programa fue escrito por Oskar Linde y nuevamente hallado__ en el grupo
de noticias. Fue construido para mostrar como el hecho de que el recolector
sea conservativo puede hacer que al leer datos binarios hayan muchos *falsos
-punteros* que mantengan vivas celdas que en realidad ya no deberían ser
+positivos* que mantengan vivas celdas que en realidad ya no deberían ser
accesibles desde el *root set* del grafo de conectividad.
__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=46407
Ambas opciones, reducen notablemente la variación en los resultados (ver
cuadro :vref:`t:sol-setarch`). Esto probablemente se debe a la naturaleza
conservativa del recolector, dado que la probabilidad de tener *falsos
-punteros* depende directamente de los valores de las direcciones de memoria,
+positivos* depende directamente de los valores de las direcciones de memoria,
aunque las pruebas en la que hay concurrencia involucrada, se siguen viendo
grandes variaciones, que probablemente estén vinculadas a problemas de
sincronización que se ven expuestos gracias al indeterminismo inherente a los
El aumento en el variación de los tiempos de ejecución al usar marcado preciso
probablemente se debe a lo siguiente: con marcado conservativo, debe estar
sobreviviendo a las recolecciones el total de memoria pedida por el programa,
-debido a falsos punteros (por eso no se observa prácticamente variación en el
+debido a *falsos positivos* (por eso no se observa prácticamente variación en el
tiempo de ejecución y memoria máxima consumida); al marcar con precisión
-parcial, se logra disminuir mucho la cantidad de falsos punteros, pero el
+parcial, se logra disminuir mucho la cantidad de *falsos positivos*, pero el
*stack* y la memoria estática, se sigue marcado de forma conservativa, por lo
tanto dependiendo de los valores (aleatorios) generados por la prueba, aumenta
-o disminuye la cantidad de falsos punteros, variando así la cantidad de
+o disminuye la cantidad de *falsos positivos*, variando así la cantidad de
memoria consumida y el tiempo de ejecución.
No se muestran los resultados para más de un procesador por ser demasiado
para TBGC se ve una variación entre los resultados muy grande que desaparece
al cambiar a CDGC, esto no puede ser explicado por esa optimización. En
general la disminución de la variación de los resultados hemos visto que está
-asociada al incremento en la precisión en el marcado, dado que los falsos
-punteros ponen una cuota de aleatoriedad importante. Pero este tampoco parece
-ser el caso, ya que no se observan cambios apreciables al pasar a usar marcado
-preciso.
+asociada al incremento en la precisión en el marcado, dado que los *falsos
+positivos* ponen una cuota de aleatoriedad importante. Pero este tampoco
+parece ser el caso, ya que no se observan cambios apreciables al pasar a usar
+marcado preciso.
Lo que se observa en esta oportunidad es un caso patológico de un mal factor
de ocupación del *heap* (ver :ref:`sol_ocup`). Lo que muy probablemente está
============== ============== ============== =================
El pequeño incremento en el tiempo total de ejecución podría estar dado por la
-mayor probabilidad de tener *falsos punteros* debido al incremento del tamaño
+mayor probabilidad de tener *falsos positivos* debido al incremento del tamaño
del *heap*; se recuerda que el *stack* y memoria estática se siguen marcado de
forma conservativa, incluso en modo preciso.