Encontrei aplicações práticas legítimas de referências fracas nos três cenários do mundo real que realmente aconteceram comigo:
Aplicativo 1: manipuladores de eventos
Você é um empreendedor. Sua empresa vende um controle de linhas de faísca para o WPF. As vendas são ótimas, mas os custos de suporte estão acabando com você. Muitos clientes estão reclamando de sobrecargas de CPU e vazamentos de memória quando percorrem telas cheias de linhas de faísca. O problema é que o aplicativo está criando novas linhas de ignição à medida que elas são exibidas, mas a vinculação de dados impede que as antigas sejam coletadas como lixo. O que você faz?
Apresente uma referência fraca entre a vinculação de dados e seu controle, de forma que a vinculação de dados não evite mais que seu controle seja coletado como lixo. Em seguida, adicione um finalizador ao seu controle que destrói a vinculação de dados quando é coletada.
Aplicativo 2: gráficos mutáveis
Você é o próximo John Carmack. Você inventou uma nova representação gráfica baseada em gráficos de superfícies de subdivisão hierárquica que faz os jogos de Tim Sweeney parecerem um Nintendo Wii. Obviamente, eu não vou dizer exatamente como funciona, mas tudo gira em torno desse gráfico mutável onde os vizinhos de um vértice pode ser encontrado em um Dictionary<Vertex, SortedSet<Vertex>>
. A topologia do gráfico continua mudando conforme o jogador corre. Há apenas um problema: sua estrutura de dados está eliminando subgráficos inalcançáveis enquanto é executada e você precisa removê-los ou perderá memória. Felizmente você é um gênio, então você sabe que há uma classe de algoritmos projetados especificamente para localizar e coletar subgrafos inacessíveis: coletores de lixo! Você leu a monografia excelente de Richard Jones sobre o assunto , mas deixa você perplexo e preocupado com seu prazo iminente. O que você faz?
Simplesmente substituindo seu Dictionary
por uma tabela hash fraca, você pode pegar o GC existente e fazer com que ele colete automaticamente seus subgráficos inacessíveis para você! De volta a folhear anúncios da Ferrari.
Aplicativo 3: Decorando árvores
Você está pendurado no teto de uma sala cíclica em um teclado. Você tem 60 segundos para analisar alguns BIG DATA antes que alguém encontre você. Você veio preparado com um analisador baseado em fluxo que depende do GC para coletar fragmentos de AST depois de terem sido analisados. Mas você percebe que precisa de metadados extras em cada AST Node
e precisa disso rapidamente. O que você faz?
Você pode usar um Dictionary<Node, Metadata>
para associar metadados a cada nó, mas, a menos que você o limpe, as referências strongs do dicionário aos nós AST antigos os manterão vivos e vazarão memória. A solução é uma tabela hash fraca que mantém apenas referências fracas a chaves e o lixo coleta ligações de valor-chave quando a chave fica inacessível. Em seguida, à medida que os nós AST se tornam inacessíveis, eles são coletados como lixo e sua ligação de valor-chave é removida do dicionário, deixando os metadados correspondentes inacessíveis para que também sejam coletados. Então, tudo o que você precisa fazer depois que seu loop principal é terminado é deslizar de volta pela ventilação, lembrando-se de substituí-lo assim que o segurança entrar.
Note que em todos esses três aplicativos do mundo real que realmente aconteceram comigo eu queria que o GC coletasse da forma mais agressiva possível. É por isso que essas são aplicações legítimas. Todo mundo está errado.