Pular para o conteúdo

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 ms

Congelar, e os limiares#

SímboloO 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ãoPor quê
a arena cresce quando acaba, e conta que cresceutravar seria pior; crescer calado esconderia que ela foi dimensionada errada
devolver o que não veio dela é recusadoo 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