Garbage collection no Ruby
-
Upload
lauro-caetano -
Category
Software
-
view
86 -
download
0
description
Transcript of Garbage collection no Ruby
Garbage Collection Ruby
Gerenciamento manual de memória
Objeto 01 Objeto 02
Desalocar manualmente
Objeto 01 Objeto 02
Objeto 01
Mas imagine o seguinte cenário
Objeto 01 Objeto 02
Objeto 01 Objeto 02
Referência para um objeto que não existe mais
Seu sistema pode quebrar
Ou pior…
Ele pode gerar resultados incorretos
Outras preocupações além do domínio da aplicação
Entender como os módulos que você utiliza gerenciam sua memória
Lauro Caetano @laurocaetano
Open Source
Rails
Rails core team
O que é Garbage Collection e como ele foi evoluindo a cada nova versão do Ruby
Agenda• O que é Garbage Collection
• Garbage Collection no Ruby - Mark and sweep
• Desvantagens do Mark and Sweep
• Evolução
• Lazy Sweep - Ruby 1.9
• Bitmap Mark - Ruby 2.0
• Generational Garbage Collection - Ruby 2.1
O que é Garbage Collection?
Gerenciamento dinâmico automático de memória
3 Responsabilidades
1. Alocar espaço para novos objetos
2. Identificar os objetos ainda vivos
3. Recuperar o espaço ocupado por objetos
mortos
Garbage Collection no Ruby
Ruby ainda utiliza o mesmo algoritmo que foi inventado a mais
de 50 anos por John MacCarthy
Mark-Sweep
Free List
Hora de limpar o Heap
Stop the world
Percorre todos os objetos do heap e marca os que
ainda estão vivos
Varre novamente o heap, mas agora em busca dos objetos não marcados e os remove do heap
Volta a executar o seu programa
Vamos ao código
!
1 def new! 2 ref = allocate! 3 ! 4 if ref.nil?! 5 collect! 6 ! 7 if ref.nil?! 8 raise "Out of memory"! 9 end!10 end!11 end!!!
12 !13 def collect!14 mark_from_roots!15 sweep(@heap_start, @heap_end)!16 end!17 !!!
17 !18 def mark_from_roots!19 initialize(worklist)!20 !21 @roots.each do |fld|!22 ref = fld!23 if !ref.nil? && !marked?(ref)!24 set_marked(ref)!25 mark!26 end!27 end!28 end!29
!
32 !33 def mark!34 while(@worklist.any?)!35 ref = remove(worklist)!36 !37 pointers(ref).each do |fld|!38 child = fld!39 !40 if !child.nil? && !marked?(child)!41 set_marked(child)!42 add(@worklist, child)!43 end!44 end!45 end!46 end!47
47 !48 def sweep(heap_start, heap_end)!49 scan = start!50 !51 while (scan < heap_end)!52 if marked?(scan)!53 unset_marked(scan)!54 else!55 free(scan)!56 end!57 !58 scan = next_object(scan)!59 end!60 end
Desvantagens do Mark and sweep
Fazer Full GC toda hora que o heap está cheio não
parece uma boa ideia
Stop the world
Mark and sweep é proporcional ao tamanho
do heap
Evolução
Lazy Sweep Ruby 1.9
Fazer Full GC toda hora que o heap está cheio não
parece uma boa ideia
Recuperar apenas o espaço necessário para criar um novo
objeto e permitir que a aplicação continue rodando
Agora o sweep não para mais o mundo todo
A alocação é responsável por checar se existe
espaço disponível
Caso não tenha espaço disponível, fazer Lazy Sweep
até obter o espaço necessário
12 !13 def allocate(size)!14 result = remove(size)!15 !16 if result.nil?!17 lazy_sweep(size)!18 result = remove(size)!19 end!20 !21 result!22 end!23
Bitmap Mark Ruby 2.0
Como os bits de marcação no ficavam objeto, os valores
eram sempre diferentes
Para possibilitar que o Unix compartilhe valores iguais
Os bits de marcação foram movidos para uma
tabela de bitmap
1 1 1 1 10 0
Generational Garbage Collection Ruby 2.1
Mark and sweep é proporcional ao tamanho
do heap
Weak generational hypothesis
O coletor processa mais frequentemente objetos novos do que objetos
maduros
Um objeto maduro é aquele que permanece ativo por
um algum período de tempo
Enquanto um objeto novo é aquele que seu sistema
acabou de criar
Geração Nova Geração Madura
Quando o mark and sweep terminar, os objetos restantes serão considerados maduros
Geração Nova Geração Madura
Geração Nova Geração Madura
Objetos maduros não serão marcados novamente
até um próximo full GC
Quando o full GC ocorrer, todos os objetos passarão
pelo mark and sweep
É legal entender como as coisas funcionam
Bonus
JRuby and Rubinius.
Copying Garbage Collection
Segmento de memória contínua
Bump Allocation
Aloca segmentos adjacentes de memória, mantendo um ponteiro
para a próxima alocação
Próxima alocação
Próxima alocação
Próxima alocação
Objetos podem ser de tamanhos diferentes
A grande vantagem é que valores relacionados ficam
próximos
A CPU pode cachear a região de memória que for acessada frequentemente
Também utiliza o Garbage Collection Generacional
Ruby 2.2
GC Simbolos
https://bugs.ruby-lang.org/issues/9634