Pergunta

Eu uso boost :: shared_ptr na minha aplicação em C ++. O problema de memória é realmente sério, ea aplicação leva grande quantidade de memória.

No entanto, porque eu coloquei todo objeto newed em um shared_ptr, quando sai do aplicativo, sem vazamento de memória pode ser detectado.

Deve haver alguma coisa como piscina std::vector<shared_ptr<> > segurando o recurso. Como posso saber quem detém o shared_ptr, quando a depuração?

É difícil linha de código de revisão por linha. Muito código ...

Muito obrigado!

Foi útil?

Solução

Você não pode saber, apenas olhando para um shared_ptr, onde os "ponteiros irmãos" são. Você pode testar se um é unique() ou obter o use_count(), entre outros métodos .

Outras dicas

O uso generalizado popular de shared_ptr quase inevitavelmente causa ocupação de memória indesejada e invisível.

referências cíclicas são uma causa conhecida e alguns deles podem ser indireta e difícil de detectar, especialmente em código complexo que é trabalhado por mais de um programador; um programador pode decidir de um objeto precisa de uma referência para outro como uma solução rápida e não tem tempo para examinar todo o código para ver se ele está fechando um ciclo. Este perigo é extremamente subestimada.

Menos bem entendido é o problema de referências inéditas. Se um objeto é compartilhado com muitos shared_ptrs então ele não será destruído até que cada um deles é zerado ou sai do escopo. É muito fácil ignorar uma dessas referências e acabar com objetos ocultos invisível na memória que você pensou que tinha acabado com.

Embora estritamente falando estes não são vazamentos de memória (tudo vai ser lançado antes de sair do programa) que são tão prejudiciais e mais difícil de detectar.

Estes problemas são as consequências de falsas declarações de expediente: 1. Declarar o que você realmente quer ser propriedade única como shared_ptr. scoped_ptr seria correcto mas, em seguida, qualquer outra referência a esse objecto terá que ser um ponteiro em bruto, que pode ser deixado pendurado. 2. Declarar o que você realmente quer ser uma referência passiva observando como shared_ptr. weak_ptr seria correto, mas então você tem o incômodo de convertê-lo para share_ptr cada vez que você quiser usá-lo.

Eu suspeito que o seu projecto é um bom exemplo do tipo de problema que esta prática você pode obter em.

Se você tem uma aplicação intensiva de memória você realmente precisa de propriedade única para que seu projeto pode controlar explicitamente vida dos objetos.

Com única propriedade opObject = NULL; vai certamente excluir o objeto e ele vai fazê-lo agora.

Com propriedade compartilhada spObject = NULL; ........ quem sabe? ......

Uma solução para pendurados ou circulares referências de ponteiro inteligente que fizemos é personalizar a classe ponteiro inteligente para adicionar uma função de depuração somente contabilidade. Sempre que um ponteiro inteligente adiciona uma referência a um objeto, é preciso um rastreamento de pilha e coloca-lo em um mapa cuja cada entrada mantém o controle de

  1. O endereço do objeto que está sendo alocado (o que o ponteiro aponta a)
  2. Os endereços de cada objeto ponteiro inteligente segurando uma referência ao objeto
  3. Os stacktraces correspondentes de cada ponteiro inteligente quando foi construído

Quando um ponteiro inteligente sai do escopo, a sua entrada no mapa é excluído. Quando o último ponteiro inteligente a um objeto é destruído, o objeto pointee obtém sua entrada no mapa removida.

Então nós temos um comando "vazamentos de pista", com duas funções: '[re] começar a controlar vazamento' (que limpa todo o mapa e ativado rastreamento se não já), e 'imprimir referências abertas', que mostra todos os pendentes referências ponteiro inteligente criado desde o comando 'iniciar rastreamento de vazamento' foi emitido. Desde que você pode ver os rastreamentos de pilha de onde esses ponteiros inteligentes veio a ser, você pode facilmente saber exatamente quem está mantendo de seu objeto sendo liberado. Ele atrasa as coisas quando seu sobre, por isso não deixá-lo ligado o tempo todo.

É uma boa quantidade de trabalho para implementar, mas definitivamente vale a pena se você tem uma base de código em que isso acontece muito.

Você pode estar sofrendo um vazamento de memória ponteiro compartilhado via ciclos. O que acontece é seus objetos compartilhados podem realizar referências a outros objetos compartilhados que volta, eventualmente, levar ao original. Quando isso acontece o ciclo mantém todas as contagens de referência em 1 mesmo que ninguém mais pode acessar os objetos. A solução é ponteiros fracos .

Tente refatoração alguns dos seu código para que a propriedade é expressa mais explicitamente pelo uso de ponteiros fracos em vez de ponteiros compartilhados em alguns lugares.

Ao olhar para a sua hierarquia de classes, é possível determinar qual classe realmente deve manter um ponteiro compartilhado e que apenas precisa de apenas o fraco, para que possa evitar ciclos se houver algum e se o "real" objeto proprietário é destruído, "não-proprietário" objetos já deveria ter sido ido. Se se verificar que alguns objetos ponteiros perder muito cedo, você tem que olhar para seqüência de destruição objeto em seu aplicativo e corrigi-lo.

Você está, obviamente, segurando referências a seus objetos dentro de sua aplicação. Isso significa que você é, de propósito, manter as coisas na memória. Isso significa que, você não tem um vazamento de memória. Um vazamento de memória ocorre quando a memória é alocada, e então você não manter uma referência ao seu endereço.

Basicamente, você precisa de olhar para o seu design e descobrir por que você está mantendo tantos objetos e dados na memória, e como você pode minimizá-lo.

A única possibilidade de que você tem um vazamento pseudo-memória é que você está criando mais objetos do que você pensa que é. Tente colocar pontos de interrupção em todas as declarações que contêm um 'novo'. Veja se o seu aplicativo está construindo mais objetos do que você pensou que deveria, e depois ler através desse código.

O problema é realmente não é tanto uma memória de vazamento, pois é uma questão de projeto da sua aplicação.

Eu ia sugerir o uso UMDH se você estiver em janelas. É uma ferramenta muito poderosa. Use-o encontrar alocações por operação / período de tempo que você espera para ser liberado, em seguida, descobrir quem está segurando-los.

Não há mais informações sobre esta resposta SO Encontrar vazamentos de memória causados ??por ponteiros inteligentes

Não é possível dizer quais objetos própria shared_ptr de dentro do programa. Se você estiver em Linux, uma maneira de depurar os vazamentos de memória é a Valgrind ferramenta - enquanto ele não vai diretamente responder à sua pergunta, ele vai dizer onde a memória foi alocado, que é geralmente suficiente para corrigir o problema. Imagino que o Windows tem ferramentas comparáveis, mas estou não sei qual é o melhor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top