BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Notícias Lançado Ruby 2.2.0, Incluindo Coleta de Lixo Incremental e de Símbolos

Lançado Ruby 2.2.0, Incluindo Coleta de Lixo Incremental e de Símbolos

O Ruby 2.2.0, lançado em 25 de dezembro, foi o presente que os rubistas ganharam de natal. Dentre os destaques estão diversas melhorias na coleta de lixo (garbage collection - GC). Agora existe um novo algoritmo incremental de coleta de lixo e os símbolos agora passam a ser processados pelo GC. O Ruby também ganhou uma coleção de melhorias de menor relevância nas classes de núcleo e na biblioteca padrão da linguagem.

Após a introdução da coleta de lixo geracional no Ruby 2.1.0, que melhorou significativamente a taxa de transferência da GC, os mantenedores do Ruby continuam a introduzir mudanças importantes nesta área. A coleta de lixo geracional (RGenGC) classifica os objetos em gerações, pressupondo que a maioria deles tem um ciclo de vida curto. Este pressuposto possibilita alto rendimento e baixo tempo de espera em objetos mais novos, pois os mais antigos serão avaliados para exclusão somente quando não houver mais memória. Isto significa que os objetos mais antigos ainda sofrem com longos tempos de pausa.

A coleta de lixo incremental, construída sobre a coleta de lixo geracional, tem por objetivo cortar os tempos de espera mantendo o mesmo rendimento. Ela alcança tempos de pausa mais curtos intercalando a fase de marcação, na qual objetos são marcados para coleta de lixo, durante a execução padrão do Ruby. Antes da versão Ruby 2.2.0 a fase de marcação era realizada em um único grande passo.

Tanto o RGenGC como o RIncGC não são capazes de gerenciar todos os objetos, o que significa que alguns objetos nunca serão promovidos a gerações mais antigas. Isto se deve, em sua maioria, a utilização de extensões da linguagem C já que é impossível garantir que todas elas respeitem as restrições exigidas pelo RGenGC e RIncGC. Koichi Sasada apresentou na RubyConf2014 uma descrição detalhada do RGenGC e do RIncGC. É uma leitura interessante para aqueles que querem conhecer todos os detalhes do algoritmo e comparativos de desempenho.

RIncGC does multiple small mark phases instead of a big one.

Coleta de Lixo "Pare o mundo (Stop the World)" versus Coleta de Lixo Incremental. Fonte: Koichi Sasada.

RIncGC eliminates long pauses.

O RIncGC elimina longos tempos de espera. Fonte: Koichi Sasada.

A introdução da coleta de lixo para símbolos, um tipo de identificador de strings, também melhora o gerenciamento de memória do Ruby. Isto tanto é verdade que o Ruby on Rails 5.0, planejado para o Outono de 2015 (i.e Outono americano, que vai de setembro a dezembro), vai suportar apenas o Ruby 2.2+ devido a esta mudança:

O Rails 5.0 vai funcionar apenas com Ruby 2.2.0 ou versões superiores. Existem muitas otimizações interessantes na versão 2.2 do Ruby, mas a mais importante para o Rails é que os símbolos serão coletados pelo coletor de lixo. Isto significa que podemos nos livrar do peso relacionado aos malabarismos realizados quando aceitamos entradas de dados do mundo externo. Também significa que nós podemos converter completamente para os keyword arguments, e todas as outras coisas boas da última versão do Ruby.

Até agora, os símbolos não podiam ser coletados pelo coletor de lixo porque o Ruby mapeava internamente cada símbolo para um valor inteiro. O CRuby - Ruby é escrito em C - usa este valor inteiro como a identidade do símbolo. Se fosse permitido que um símbolo pudesse ser coletado no contexto Ruby e então recriado mais tarde, ele teria de receber um identificador inteiro distinto no contexto CRuby, o que significaria que um mesmo símbolo teria na prática valores distintos, e de acordo com a especificação da linguagem Ruby, isto seria um bug.

A solução mais simples seria substituir o identificador inteiro usado no CRuby por uma string, tornando assim ambos os mundos (C e Ruby) coerentes. Mais uma vez, as extensões de C complicaram o cenário já que elas impedem o gerenciador de execução de detectar e gerenciar todos os símbolos. A solução adotada foi classificar os símbolos em dois grupos: mortais e imortais. Símbolos imortais continua a utilizar identificadores de valores inteiros e portanto nunca são coletados. Exemplos de símbolos imortais incluem nomes de métodos e variáveis, constantes e outros elementos da linguagem. Símbolos mortais, como por exemplo "foo".to_sym, não possuem um valor inteiro como identificador e portanto são coletados pelo coletor de lixo.

Símbolos Mortais versus Símbolos Imortais. Fonte: Narihiro Nakamura.

Narihiro Nakamura descreveu a solução de coleta de lixo para símbolos e todas as limitações que levaram até ela na RubyKaigi2014.

Ainda no campo de gerenciamento de memória, o Ruby 2.2.0 inclui a opção de usar jemalloc ao invés da instrução de sistema malloc, para possivelmente melhorar o desempenho e diminuir a fragmentação da memória. Esta é uma funcionalidade experimental até que mais dados de desempenho e casos de uso sejam reunidos.

Os métodos de criação de processos, como system() e spawn() agora utilizam, se disponível, vfork(2) ao invés de fork(). Esta alteração pode trazer melhorias de desempenho, especialmente quando o processo pai consome muita memória. Esta também é uma funcionalidade experimental e portanto pode ser alterada no futuro.

As bibliotecas de núcleo da linguagem agora suportam Unicode 7.0 e incluem diversos novos métodos como Enumerable#slice_after, Enumerable#slice_when,Float#next_float, Float#prev_float,File.birthtime, File#birthtime e String#unicode_normalize.

O Ruby 2.2.0 deprecou a biblioteca mathn e atualizou diversas outras:

  • Psych 2.0.8

  • Rake 10.4.2

  • RDoc 4.2.0

  • RubyGems 2.4.5

  • test-unit 3.0.8

  • minitest 5.4.3

Você pode encontrar mais detalhes, incluindo algumas notas de quebra de compatibilidade e de elementos deprecados da API C no artigo de novidades do Ruby 2.2.0. O Ruby 2.2.0 teve 1.557 arquivos alterados, incluindo 125.039 inserções e 74.376 exclusões a partir da versão Ruby 2.1.0.

 

 

 

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT