Não tenha medo, veja crescer

Neste post falarei sobre minhas desventuras com ponteiros inteligentes shared_ptr. Depois de implementar a geração do próximo nível em meu jogo Death-Mask, notei uma memória vazar . Cada novo nível proporcionou um aumento de + 1 megabyte na RAM consumida. É Obviamente que alguns objetos permaneceram na memória e não a liberaram. Para corrigir este facto, foi necessário implementar a correcta implementação de recursos quando o nível se encontra sobrecarregado, o que aparentemente não foi feito. Como usei ponteiros inteligentes, havia várias opções para resolver esse problema, a primeira envolvia a revisão manual do código (longa e enfadonha), enquanto a segunda envolvia pesquisar os recursos do depurador lldb e do código-fonte libstdc++ para a possibilidade de rastreamento automático contra alterações.

Na Internet, todos os conselhos se resumiam a revisar manualmente o código, corrigi-lo e bater-se com chicotes depois de encontrar a linha de código problemática. Também foi proposta a implementação de um sistema próprio para trabalhar com memória, como fazem todos os grandes projetos desenvolvidos desde as décadas de 90 e 2000, antes da chegada dos ponteiros inteligentes no padrão C++11. Tentei usar pontos de interrupção no construtor de uma cópia de todos os shared_ptrs, mas depois de vários dias nada de útil aconteceu. Houve uma ideia de adicionar log à biblioteca libstdc++, mas os custos de mão de obra acabaram sendo monstruosos.


Cowboy Bebop (1998)

A solução me ocorreu de repente na forma de rastrear alterações na variável privada shared_ptr – use_count. Isso pode ser feito usando watchpoints embutidos no lldb. Depois de criar um shared_ptr via make_shared, as alterações no contador no lldb podem ser rastreadas usando a linha:
.

assistir definir var camera._M_refcount._M_pi->_M_use_count

Onde a “câmera” este é um objeto shared_ptr cujo estado do contador precisa ser rastreado. Claro, os aspectos internos do shared_ptr irão variar dependendo da versão do libstdc++, mas o princípio geral pode ser entendido. Após instalar o watchpoint, iniciamos os aplicativos e lemos o stacktrace de cada alteração do contador, depois olhamos o código (sic!), encontramos o problema e corrigimos. No meu caso, os objetos não foram liberados das tabelas de cache e das tabelas lógicas do jogo. Espero que este método ajude você a lidar com vazamentos ao trabalhar com shared_ptr e ame ainda mais essa ferramenta de memória. Boa depuração.

Leave a Comment

Your email address will not be published. Required fields are marked *