O coletor sob controle
Desligar o coletor não vaza memória — a distinção que quase todo mundo erra. Mais congelar, limiares e a arena.
dataforge
adopt Arcane.Memoria as Mem
action critico():
total := 0
cycle i from 1 to 100:
total += i
yield total
assert Mem.gc_ligado()
// sem coletor no trecho sensivel — e ele volta depois, SEMPRE
assert Mem.sem_gc(critico) is 5050
assert Mem.gc_ligado()O finally do sem_gc não é detalhe: deixar o coletor desligado por causa de um erro é muito pior que a pausa que se queria evitar — e o programa seguiria assim até terminar, sem nada denunciando. Há teste cobrando isso com um corpo que falha.
A medida, e não a promessa#
A frase "desligar o coletor reduz pausa" seria fé sem número. O teste mede a mesma carga dos dois jeitos, e o que ele mede é o tempo que o coletor passou parando o programa:
6000 ciclos alocados
com o coletor ligado pausas: 3 total: 1,84 ms
com o coletor desligado pausas: 0 total: 0,00 msCongelar, e os limiares#
| Símbolo | O que faz |
|---|---|
Mem.gc_congelar() | tira o que já vive das varreduras, para sempre — o que um servidor faz depois da carga e antes do primeiro pedido |
Mem.gc_limiares() | lê os três; com três argumentos, ajusta |
Mem.gc_geracoes() | quantas coletas houve em cada geração, e quanto cada uma rendeu |
Mem.coletar(geracao) | força uma coleta agora |
dataforge
adopt Arcane.Memoria as Mem
assert len(Mem.gc_limiares()) is 3
assert len(Mem.gc_geracoes()) is 3
antes := Mem.gc_congelados()
Mem.gc_congelar()
assert Mem.gc_congelados() bigger antes
Mem.gc_descongelar()Arena#
Não é um allocator: quem aloca continua sendo o Python, e não há como trocá-lo por dentro. O que a arena troca é o padrão de uso — em vez de criar e descartar por volta, um lote é preparado, emprestado e devolvido.
dataforge
adopt Arcane.Memoria as Mem
arena := Mem.arena(3, lambda => {"n": 0})
a := Mem.pegar(arena)
Mem.devolver(arena, a)
b := Mem.pegar(arena) // o MESMO objeto volta
e := Mem.arena_estatisticas(arena)
assert e["criados"] is 3 // o lote, preparado de uma vez
assert e["reaproveitados"] is 1
assert e["em_uso"] is 1| Decisão | Por quê |
|---|---|
| a arena cresce quando acaba, e conta que cresceu | travar seria pior; crescer calado esconderia que ela foi dimensionada errada |
| devolver o que não veio dela é recusado | o lote cresceria com estranhos, e o próximo pegar entregaria um deles |
limpar solta o lote inteiro numa chamada | é o tempo de vida de arena da literatura, e a operação que ela existe para ter |