memory - trabajando - Apagar el recolector de basura D
recolectores de basura (4)
El GC se puede quitar y reemplazar con un envoltorio simple alrededor de malloc / free.
Soy un programador de C ++ que está considerando usar D para un proyecto personal con el que quiero jugar. Me preguntaba si hay una forma de desactivar por completo el recolector de basura, y cuáles son los riesgos de hacerlo.
Sé que puedo administrar mi propia memoria anulando new y delete para usar malloc y free, pero si lo hiciera prefiero que el recolector de basura no se ejecute en absoluto.
Estaba leyendo acerca del lenguaje D y encontré esto en las especificaciones que parecen nuevas en D:
40. Mejor C
-betterC es un indicador de línea de comandos para dmd, que restringe la compatibilidad del compilador con ciertas características de tiempo de ejecución. En particular, los programas D o las bibliotecas compiladas con betterC no están vinculadas con Druntime. El uso de las características de tiempo de compilación no está restringido de ninguna manera. https://dlang.org/spec/betterc.html
Una de las consecuencias del uso de este indicador de línea de comando es deshabilitar las funciones de GC y de idioma que se transmiten en él.
40.1 Consecuencias
Como no hay Druntime disponible, muchas características D no funcionarán. Por ejemplo:
- Recolección de basura
- Almacenamiento local de subprocesos
- TypeInfo y ModuleInfo
- Clases
- Enhebrado incorporado (por ejemplo, core.thread)
- Arrays dinámicos (pero no sectores) y matrices asociativas
- Excepciones
- cambiar con cuerdas
- cambio final
- sincronizado y core.sync
- Constructores o deconstructores de módulos estáticos
- Struct deconstructors
- unittest (la prueba puede ser como siempre con el indicador -betterC)
ver también https://dlang.org/blog/2017/08/23/d-as-a-better-c/
Para apagar el GC en D2:
import core.memory;
void main(string[] args) {
GC.disable;
// Do stuff.
}
Si usa D1 / Phobos:
import std.gc;
void main(char[][] args) {
std.gc.disable;
// Do stuff.
}
En D1 / Tango:
import tango.core.Memory;
void main(char[][] args) {
GC.disable;
// Do stuff.
}
El GC se puede reactivar de manera similar llamando a GC.enable (D2 o D1 / Tango) o std.gc.enable (D1 / Phobos). Esto se puede hacer en cualquier punto de un programa. Internamente, se usa un contador, y para volver a habilitar GC, debe llamar a enable () una vez por cada vez que se invoca disable ().
Aquí hay algunas cosas que no se deben hacer con GC deshabilitado, ya que causarán pérdidas de memoria:
- No use el operador array append (~ =), o use la propiedad .length para agrandar una matriz que ya ha sido asignada. Estos se basan en GC para liberar la matriz anterior si tiene que ser reasignada, ya que puede haber un alias en otra parte del programa.
- No use arrays asociativos incorporados. La única manera de liberar estos es por GC.
- La mayoría de Phobos y, creo, Tango, fueron diseñados con la suposición de que la recolección de basura está presente. Las funciones de estas bibliotecas pueden provocar pérdidas de memoria horribles si se utilizan sin GC.
- No use cierres D2 con GC desactivado. (No es que lo harías de todos modos, para un juego).
Dicho esto, mientras que D está diseñado para ser utilizado con el GC desactivado en algunas piezas críticas de código (el tipo de piezas críticas donde existen restricciones de tiempo real y probablemente no se debe usar ninguna forma de malloc no diseñada explícitamente para tiempo real computar de todos modos), fue diseñado en gran medida con la suposición de que GC estaría presente. En su caso, todavía puede usar GC para todas las cosas de inicialización, etc. y solo desactivarlo cuando llegue a la parte de su juego que realmente necesita ser en tiempo real.
Como nota al margen, GC y la gestión manual de la memoria pueden coexistir en D, y en la práctica, cuando se optimiza el código, la eliminación manual de algunos objetos grandes con tiempos de vida triviales puede dar como resultado aceleraciones significativas. Esto se puede hacer de manera similar a C ++, utilizando una declaración de eliminación, y es seguro de hacer, incluso si el GC está habilitado. Cuando no tiene restricciones de tiempo real, esto le brinda la mayoría de los beneficios de GC con la mayor parte del rendimiento de la administración de memoria manual.
Si desea utilizar malloc y el uso gratuito de std.c.stdlib . GC nunca los tocará. std.gc tiene todas las cosas que necesitará para la administración de la memoria, incluyendo disable ().
GC no es algo malo, sin embargo. La mayoría, si no todas, las bibliotecas en D tendrán un lugar en el código donde la memoria no se elimine explícitamente, por lo que no te convertirán en un héroe para tenerlo siempre apagado, pero está bien si tienes algún requisito de rendimiento crítico.
GC hace que todo sea mucho más productivo, como el corte de matrices y la creación de nuevos objetos en parámetros sin que la persona que llama almacene una referencia en ellos. El código bueno es mucho menos y con el código GC se vuelve mucho más pequeño.