- Não tema o ceifador
- Vida na pista rápida
- Go Your Own Way. .
- Go Your Own Way. .
Na primeira de uma série no GC, apresentei o coletor de lixo D e os recursos de idioma que o utilizam. Dois pontos-chave que tentei transmitir:
O GC é executado somente quando você solicita uma alocação de memória . Ao contrário do equívoco popular, o GC da linguagem D não pode simplesmente pausar e pausar seu clone do Minecraft no meio de um ciclo de jogo. Só é executado quando você solicita memória através dele e somente quando necessário.
Estratégias simples de alocação de memória no estilo C e C ++ podem reduzir a carga no GC . Não aloque memória dentro de loops - em vez disso, pré-aloque o máximo de recursos possível ou use a pilha. Minimize o número total de alocações de memória através do GC. Essas estratégias funcionam por causa do nº 1. O desenvolvedor pode determinar quando executar a coleta de lixo usando inteligentemente a alocação de heap gerenciada por GC.
As estratégias do ponto 2 são adequadas para o código que o programador escreve, mas não são particularmente úteis quando se trata de bibliotecas de terceiros. Nesses casos, usando os mecanismos da linguagem D e seu tempo de execução, você pode garantir que nenhuma alocação de memória ocorra em pontos críticos do código. Também existem opções de linha de comando para ajudar a garantir que o GC não atrapalhe.
Vamos imaginar que você esteja escrevendo um programa em D e, por um motivo ou outro, resolva eliminar completamente a coleta de lixo. Você tem duas soluções óbvias.
Comprimido para ganância
A primeira solução é ligar GC.disablequando o programa for iniciado. A alocação de memória via GC ainda funcionará, mas a coleta de lixo será interrompida. Toda a coleta de lixo, incluindo o que pode ter acontecido em outros threads.
void main() {
import core.memory;
import std.stdio;
GC.disable;
writeln("Goodbye, GC!");
}
Resultado:
Goodbye, GC!
, , .
, . , - , . GC.enable GC.collect. , C C++.
, @nogc. main, .
@nogc
void main() { ... }
GC. @nogc, main, , . « ».
, GC.disable. .
@nogc
void main() {
import std.stdio;
writeln("GC be gone!");
}
:
Error: @nogc function 'D main' cannot call non-@nogc function 'std.stdio.writeln!string.writeln'
(: @nogc- 'D main' -@nogc– 'std.stdio.writeln!string.writeln')
@nogc , . . @nogc, , , @nogc. , writeln .
:
@nogc
void main() {
auto ints = new int[](100);
}
:
Error: cannot use 'new' in @nogc function 'D main'
(: 'new' @nogc- 'D main')
@nogc- , GC ( ). . , , GC . , , @nogc, .
, @nogc , . , , - ( ). — . :
throw new Exception("Blah");
- , new, @nogc- . , , , - , … , . D , , throw new Exception GC, .
, @nogc- . (. .) @nogc main — , .
, : @nogc main GC . D . main, — . @nogc, , , GC @nogc-. , @nogc, main, , main , , GC.
. , D, GC . , GC — . , , D: GC . , , .
, , , GC. @nogc / API core.memory.GC . @nogc main, , GC. GC.disable . , GC.enable. , GC (, ), GC.collect.
, , , . API core.memory.GC GC . D.
( !) D --DRT-gcopt=profile:1, . GC, , .
: gcstat.d .
void main() {
import std.stdio;
int[] ints;
foreach(i; 0 .. 20) {
ints ~= i;
}
writeln(ints);
}
GC:
dmd gcstat.d
gcstat --DRT-gcopt=profile:1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Number of collections: 1
Total GC prep time: 0 milliseconds
Total mark time: 0 milliseconds
Total sweep time: 0 milliseconds
Total page recovery time: 0 milliseconds
Max Pause Time: 0 milliseconds
Grand total GC time: 0 milliseconds
GC summary: 1 MB, 1 GC 0 ms, Pauses 0 ms < 0 ms
, , , . D GC , ( ) . , , D , GC - ( ).
DMD -vgc, GC — , , ~=.
: inner.d.
void printInts(int[] delegate() dg)
{
import std.stdio;
foreach(i; dg()) writeln(i);
}
void main() {
int[] ints;
auto makeInts() {
foreach(i; 0 .. 20) {
ints ~= i;
}
return ints;
}
printInts(&makeInts);
}
makeInts — . , , / ( static, delegate function). .
-vgc:
dmd -vgc inner.d
inner.d(11): vgc: operator ~= may cause GC allocation
inner.d(7): vgc: using closure causes GC allocation
(inner.d(11): vgc: ~= GC)
(inner.d(7): vgc: GC)
, , ints, ( — - delegate). ints makeInts . , - . printInts :
void printInts(scope int[] delegate() dg)
scope , . , dg . , . . , , .
, GC D , Java C#, . , D , Java, . , D. , Java, GC , .
, , , , . D № 2 , @nogc core.memory.GC , . , , , .
, D. , Phobos — D — @nogc. , , .
Em artigos futuros, veremos como alocar memória sem recorrer ao GC e usá-lo em paralelo com a memória do GC, do que substituir os @nogcrecursos de idioma que não estão disponíveis no código e muito mais.
Agradecemos a Vladimir Panteleev, Guillaume Piolat e Steven Schveighoffer por seus valiosos comentários sobre o rascunho deste artigo.