Press "Enter" to skip to content

String.Intern – Evitando duplicação de strings

Para aproveitar esse artigo, é bom entender o conceito de String Interning ou Tabela de Strings, pode encontrar mais sobre o assundo no meu artigo Entendendo Strings.

Esse é o primeiro de uma série de artigos onde vou mostrar algumas dicas, ferramentas e truques para analisar aplicações e identificar problemas, as vezes isso será feito só com o dump de memória da aplicação o que vai deixar o trabalho mais divertido :D.

Voltando ao assunto das Strigs, o que não falei no primeiro artigo, é que essa tabela de strings é montada em tempo de compilação, isso significa que durante a execução do sistema podemos ter strings duplicadas em memória,e no caso de uma aplicação com problemas de consumo de memória, já temos um bom lugar para começar a análise!

Nesse artigo estou utilizando a ferramenta YourKit Profiler for .NET..

Veja o código abaixo:

Nesse código incluímos 1000 vezes a string “Althmann” em uma lista, a parte boa é que em tempo de compilação isso será resolvido, e a tabela de strings vai entrar em ação, teremos só 1 “Althmann” em memória.

Mas logo abaixo adicionamos na mesma lista, um texto qualquer que o usuário digitar, é aqui que a brincadeira fica divertida. Não temos muito controle do que será informado no sistema, ou de XMLs gigantes carregados, ou seja, quase tudo vira string nos sistemas, e dependendo do tamanho das strings e da sua duplicação o consumo de memória pode ser elevado.

Nesse teste eu vou escrever 10 vezes a seguinte frase.


Preciso acabar logo o artigo porque quero jogar Diablo 3

Utilizando o YourKit Profiler, consigo executar facilmente algumas análises de possíveis memory leaks, um dos itens que ele analisa por padrão é a duplicação de strings, veja na imagem abaixo ele mostrando as 10 strings duplicadas em memória.

O bom é que a ferramenta já da dicas de possíveis formas de resolver o problema, a que vou utilizar é a String.Intern.

Veja o novo código usando agora String.Intern.

Explicando de uma forma simples, quando eu faço String.Intern(Console.ReadLine()), antes de adicionar a string na lista, será feita uma verificação se essa string já está na tabela de strings, se não estiver adiciona e se estiver retorna a referência.

Com isso repetindo novamente a frase anterior 10 vezes o YourKit Profiler não acusa mais a minha frase repetida em memória.

Simples e com ótimo resultado, então isso é regra, se eu tenho um consumo elevado de memória vou usar String.Intern?

De forma alguma! Nem tudo são flores, temos que levar em consideração performance, afinal existe uma operação para verificar se essa string já existe, mas ainda farei alguns testes mais sérios para verificar se realmente é um problema. Mais um detalhe, prestem muita atenção no texto abaixo, ao tentar resolver um problema podemos gerar outros ;).

If you are trying to reduce the total amount of memory your application allocates, keep in mind that interning a string has two unwanted side effects. First, the memory allocated for interned String objects is not likely be released until the common language runtime (CLR) terminates. The reason is that the CLR’s reference to the interned String object can persist after your application, or even your application domain, terminates. Second, to intern a string, you must first create the string. The memory used by the String object must still be allocated, even though the memory will eventually be garbage collected.

Por hoje é isso.

Abraços