Não tema o ceifador

GC Series
  1. Não tema o ceifador
  2. Vida na pista rápida
  3. Go Your Own Way. .
  4. Go Your Own Way. .


D, como muitos idiomas atualmente em uso, vem com um Garbage Collector (GC). Muitos tipos de software podem ser desenvolvidos sem pensar no GC, aproveitando ao máximo suas vantagens. No entanto, o GC tem suas falhas e a coleta de lixo não é desejável em alguns cenários. Nesses casos, o idioma permite desativar temporariamente o coletor de lixo ou até mesmo ficar sem ele.



Para tirar o máximo proveito do coletor de lixo e minimizar suas desvantagens, é necessário entender como o GC funciona na linguagem D. Um bom ponto de partida é a página Coleta de Lixo no dlang.org , que traz a justificativa para o GC na linguagem D e fornece algumas dicas sobre como trabalhar com ele. Este é o primeiro de uma série de artigos a abordar o tópico com mais detalhes.



Desta vez, abordaremos apenas o básico, concentrando-nos nas funções de linguagem que podem causar alocação de memória através do GC. Artigos futuros apresentarão maneiras de desativar o GC quando necessário, bem como expressões idiomáticas para ajudar a lidar com seu não determinismo (por exemplo, gerenciamento de recursos em destruidores de objetos sob controle do GC).



A primeira coisa a entender é que o coletor de lixo de D é acionado apenas durante a alocação de memória e somente se não houver memória para alocar. Ele não se senta no fundo, examinando periodicamente a pilha e coletando lixo. Isso deve ser entendido para escrever um código que use efetivamente a memória sob o controle do GC. Considere o seguinte exemplo:



void main() {
    int[] ints;
    foreach(i; 0..100) {
        ints ~= i;
    }
}


Este programa cria uma matriz dinâmica de valores de tipo inte, em seguida, usa o operador de junção em D para adicionar números de 0 a 99 a ele foreach. O que não é óbvio para quem não é treinado é que o operador de junção aloca memória para valores agregados por meio do coletor de lixo.



D . , . , , . , , capacity. , , .



void main() {
    import std.stdio : writefln;
    int[] ints;
    size_t before, after;
    foreach(i; 0..100) {
        before = ints.capacity;
        ints ~= i;
        after = ints.capacity;
        if(before != after) {
            writefln("Before: %s After: %s",
                before, after);
        }
    }
}


DMD 2.073.2,  — GC. , GC . . , GC, .



, before after. : 0, 3, 7, 15, 31, 63, 127. ints 100 , 27 , , 255, . , , D, . , GC , (Steve Schveighoffer) .



, , GC . , , «» . GC .



, C C++, , . ,  — , . , GC D , . :



void main() {
    int[] ints = new int[](100);
    foreach(i; 0..100) {
        ints[i] = i;
    }
}


. , — . 100 . new 100, .



: reserve:



void main() {
    int[] ints;
    ints.reserve(100);
    foreach(i; 0..100) {
        ints ~= i;
    }
}


100 , ( length 0), . , 100 , , .



new reserve, , GC.malloc.



import core.memory;
void* intsPtr = GC.malloc(int.sizeof * 100);
auto ints = (cast(int*)intsPtr)[0 .. 100];


.



auto ints = [0, 1, 2];


, enum.



enum intsLiteral = [0, 1, 2];
auto ints1 = intsLiteral;
auto ints2 = intsLiteral;


enum .  — . , . ints1, ints2 , :



auto ints1 = [0, 1, 2];
auto ints2 = [0, 1, 2];


, . , ( D — ) — .



int[3] noAlloc1 = [0, 1, 2];
auto noAlloc2 = "No Allocation!";


:



auto a1 = [0, 1, 2];
auto a2 = [3, 4, 5];
auto a3 = a1 ~ a2;


D , , . : keys values, . , , - ,  — . , GC.



- , , , . , . , . D : byKey, byValue byKeyValue. , . , , . Ranges More Range (Ali Çehreli) Programming in D.



 — ,  — . , Garbage Collection — assert. , assert , AssertError, D, ( , GC).



, Phobos — D. - - Phobos’ GC, , . , Phobos GC. , , , , , . GC (, , ,  — - ).



Agora que descobrimos o básico do trabalho com o GC, no próximo artigo desta série, veremos quais ferramentas no idioma e no compilador nos permitirão desativar o coletor de lixo e garantir que locais críticos do programa não acessem o GC.



Agradecemos a Guillaume Piolat e Steve Schweihoffer por sua ajuda na preparação deste artigo.




All Articles