- Não tema o ceifador
- Vida na pista rápida
- Go Your Own Way. .
- 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 int
e, 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];
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.