Início Tecnologia 5 maneiras de fortalecer seu código contra vazamentos de memória

5 maneiras de fortalecer seu código contra vazamentos de memória

5
0

Já ri de “abstrações com vazamentos” com seus amigos dev em uma conferência? Sim, é hilário, até que você tenha depurado um vazamento de memória às 3 da manhã, amaldiçoando seu código e bebidas energéticas.

Se você esteve lá, sabe que o sentimento de afundamento quando seu aplicativo começa a engasgar, e você está se esforçando para descobrir o porquê.

Os vazamentos de memória são os piores. Eles são como baratas na sua base de código, esgueirando -se, devorando a memória até que seu aplicativo diminua para um rastreamento ou apenas trava. Duro. E o kicker? Até o seu código mais limpo e brilhante pode se transformar em uma bagunça quente se os vazamentos ficarem fora de controle.

Mas você não precisa apenas sentar lá e levá -lo. Eu tenho suas costas com 5 maneiras de não-BS de morto, no NO-BS de proteger seu código contra vazamentos de memória. Estes são itens essenciais se você estiver trabalhando em aplicativos ou serviços de alto tráfego que precisam permanecer para sempre. Porque, honestamente, ninguém se importa com o seu código perfeito se o seu aplicativo continuar tanque.

Vamos esmagar esses vazamentos para sempre. Preparar?

5 maneiras práticas de endurecer seu código contra vazamentos de memória

1. Evite substituir Finalize () em Java

O Finalize () de Java parece útil, mas na realidade? É um desastre sob o capô. Isso cria mais problemas do que soluções. A questão é que, uma vez que você substitui o finalize (), o Java deve passar por aros extras. E quando um objeto tem um método Finalize (), Java o coloca em uma fila especial, e um thread especial o executa. Somente depois disso a memória pode ser limpa, e isso atrasa o tempo de coleta de lixo.

Objetos com Finalize () podem levar mais tempo para limpar, e é por isso que seu aplicativo pode estar desacelerando sem aviso prévio. De fato, alguns coletores de lixo não jogam bem com o Finalize (), o que leva a mais ciclos de coleta e trabalho further. O resultado? Seu aplicativo pode levar o golpe.

Aqui está a correção:

  • Implementar autoclosable com um método limpo Shut ().
  • Use o Attempt-With-Assets para que o Java possa lidar com a limpeza automaticamente.
  • Sempre verifique as subclasses duas vezes para que não herdem a lógica Finalize () silenciosamente.
  • Use fraco referência ou fantasma fantasma para armazenamento em cache.
  • Limpe constantemente recursos nativos, como alças de arquivo e soquetes

2. Use o pool de objetos em aplicativos .NET

O agrupamento de objetos é uma maneira eficaz de otimizar o uso da memória e o desempenho do aplicativo. Às vezes, quando seu aplicativo está passando por instabilidade, você pode precisar apenas reduzir como os objetos são criados, usados ​​e reutilizados. Esses são os problemas que o agrupamento de objetos visa corrigir. Na sua essência, o pool de objetos é uma maneira inteligente de reutilizar objetos existentes, em vez de criar novos do zero.

Como isso é inteligente? Ao reutilizar objetos, a pressão no coletor de lixo é levantada. E isso simplesmente aumentará o desempenho suave do aplicativo e evitará menos pausas. Essa abordagem tem dois benefícios extras: economiza memória e reduz o tempo para alocar e desalocar recursos. Isso parece uma ganha-ganha para mim.

Não ser um cocô de festa aqui. Mas aqui está um pouco de aviso: o pool pode desacelerar as coisas se você não precisar. É por isso que a Microsoft recomenda testar em cenários da vida actual antes de implementar. Siga estas etapas para descobrir como implementar o agrupamento de objetos em seus aplicativos .NET:

Aqui está a correção:

  • Use o DotMemory ou qualquer ferramenta de perfil eficiente para encontrar objetos que são frequentemente criados, mas têm vidas curtas.
  • Faça políticas personalizadas do ObjectPool que limpam os dados restantes antes de reutilizar objetos.
  • Usar os blocos Attempt/Finalmente para garantir que os objetos emprestados sejam devolvidos ao pool.
  • Understand seu aplicativo antes e depois do pool para medir o desempenho.

3. Execute a limpeza no React useeffect ganchos

Quando algo começa a correr em segundo plano que não deveria, seu aplicativo provavelmente começará a se comportar estranhamente. Esse tipo de vazamento de memória ocorre nos aplicativos React quando os componentes se apegam às coisas mesmo depois de não serem montados. Isso normalmente é resultado de tarefas assíncronas ou referências persistentes sobrevivendo os componentes que os iniciaram.

Uma instância comum é quando um ouvinte de evento ainda está ativo mesmo após a ausência do componente. Outro exemplo típico são as assinaturas de fontes de dados que nunca foram inscritas, juntamente com vários outros problemas. Felizmente, o React fornece um gancho de limpeza, uso do uso, para resolver esse problema.

Agora, os desenvolvedores podem encontrar uma maneira de limpar os componentes antes de re-fazer novamente ou desmontar. Os benefícios desta função são quase infinitos. Por fim, você pode limpar os temporizadores, cancelar assinaturas e remover ouvintes de eventos. Tudo executando uma etapa simples? Sim.

Mas o que está no topo de todos eles é que esse passo simples libera memória e mantém seu aplicativo eficiente. Quer que seus aplicativos de reação sejam estáveis ​​ao longo do tempo? Então, a limpeza é uma obrigação.

Deixe -me mostrar como fazer isso.

Aqui está a correção:

  • useeffect (() => {…}, [ ]);
  • Este gancho deve ser executado uma vez após o montamento do componente. É também onde você coloca efeitos colaterais.
  • deixe ismmouged = true;
  • Isso rastreia se o componente ainda está montado.
  • const fetchdata = async () => {…}
  • Isso busca dados de uma API externa.
  • const controller = new abortcontroller ();
  • Isso cancela uma solicitação de busca se o componente desmontar.
  • const Response = Aguarda Fetch (‘https: //api.youandme.com/knowledge’, {Sign});
  • Isso envia a solicitação HTTP actual para a API.
  • const dados = aguarda resposta. json ();
  • Isso analisa a resposta retornada, pois o JSON recebe as informações obtidas na API
  • if (ismamed) {setData (dados); }
  • Catch (Error) {…}
  • Isso captura e registra todos os erros durante a busca e ignora o AborterRor.
  • fetchdata ();
  • Isso solicita que a função assíncrona inicie o processo de busca de dados.
  • return () => {…}
  • Esta é a função de limpeza do UseEffect que é executado antes dos componentes desmontagens.
  • está montado = false;
  • Isso garante que não atualizemos o estado depois que o componente se foi.
  • Controller.abort ();
  • Isso cancela a solicitação de busca se ainda estiver em andamento e impede vazamentos de memória.

4. Repair Equals () e HashCode () nas coleções Java

É tão fácil para nós focarmos nas grandes coisas do desenvolvimento de Java, mas às vezes são os pequenos detalhes que causam os maiores problemas. Um desses pequenos detalhes: o uso adequado de iguais () e hashcode (). Não ficarei surpreso se você estiver se perguntando como esses métodos simples podem causar um vazamento de memória.

Bem, esses dois métodos aparentemente simples são o núcleo de como Java lida com objetos no hashmap ou no hashset. E se implementado incorretamente? As coisas podem descer ladeira abaixo.

Muitos desenvolvedores escorregam, substituindo iguais () e esquecem de substituir o hashcode (). Isso resultaria no recebimento e armazenamento de duplicatas. Com o tempo, o aplicativo se apegaria aos objetos que não deveria. O resultado? Bloat de memória. Isso não falhará seu aplicativo imediatamente, mas não responderá.

Aqui está a correção:

  • @0verride public boolean equals (0bject o) {/*…*/} @0verride public int hashCode () {/*…*/}
  • Faça bem em substituir os dois métodos e não apenas um método.
  • retornar 0bjects .hash (id, nome); // mesmos campos que iguais ()
  • Faça bem em tornar o HashCode () Retornar resultados consistentes para seus objetos iguais.
  • Nome da string remaining privada; // campo imutável usado em iguais/hashcode
  • Faça bem em usar campos imutáveis ​​para cálculos.
  • iguais: retornar this.id == O.id; HashCode: Return Integer.hashcode (ID);
  • Inclua os campos exatos nos dois métodos.
  1. Use referências fracas para gerenciamento de cache

O gerenciamento de memória geralmente surge como uma preocupação ao criar um cache. Obviamente, nenhum desenvolvedor deseja que seu aplicativo mantenha a memória por mais tempo do que deveria. É exatamente aí que as referências fracas intervêm. Por que as referências fracas são tão valiosas no gerenciamento do cache?

Bem, tudo se resume às suas habilidades para permitir que a memória seja recuperada, especialmente quando não está em uso. Isso significa que, se uma memória não estiver em uso, ela pode ser limpa e a referência poderá ser limpa.

É muito importante observar que diferentes plataformas oferecem diferentes variedades de referências fracas. Em JavaScript, o Frafmap e o Frawset sempre são úteis. O MAP fraco é perfeito para anexar metadados temporários a objetos sem afetar sua vida útil na memória.

Por outro lado, o fraco é ultimate ao agrupar objetos que você não precisa querer manter vivo. E em Java, a referência fraca é ótima ao criar coleções que se apegam apenas aos objetos quando o aplicativo até precisa deles.

Pensamentos finais

Uma verdade dura? Prevenir vazamentos de memória não é algo que você faz uma vez e esqueça. Você precisa construí -lo na maneira como você codifica, testar e implantar. Também requer consistência, para que você não possa simplesmente passar uma semana de fixação de vazamentos heróicos e voltar aos velhos hábitos.

As equipes que aplicam essas boas práticas de gerenciamento de memória que compartilhei têm garantia de ter aplicativos que prosperam. No remaining do dia, é um aplicativo próspero e duradouro que pode ser apreciado.

fonte

DEIXE UMA RESPOSTA

Por favor digite seu comentário!
Por favor, digite seu nome aqui