Pergunta

Em uma de minhas VB6 formas, criar vários outros objetos de Formulário e armazená-los em variáveis de membro.

Private m_frm1 as MyForm
Private m_frm2 as MyForm

// Later...
Set m_frm1 = New MyForm
Set m_frm2 = New MyForm

Eu notar que eu sou uma fuga de memória quando este (pai) formulário é criado e destruído.É necessário, para mim, para atribuir estas variáveis membro Nothing no Form_Unload()?

Em geral, quando é exigido?

RESOLVIDO:Neste particular vazamento de memória foi corrigido quando eu fiz um Unload sobre os formulários em questão, não quando eu definir o formulário Nothing.Eu consegui remover alguns outros vazamentos de memória definindo explicitamente algumas instâncias de Módulos de Classe Nothing, bem.

Foi útil?

Solução

@Matt Dillard - Fez definindo esses nada a corrigir a sua fuga de memória?

VB6 não formal, coletor de lixo, mais ao longo das linhas de que @Konrad Rudolph disse.

Na verdade, chamar de descarregar os formulários parece-me ser a melhor forma de garantir que o formulário principal é limpo e que cada subformulário limpa suas ações.

Eu testei isso com um projeto em branco e dois formulários em branco.

Private Sub Form_Load()
  Dim frm As Form2
  Set frm = New Form2
  frm.Show
  Set frm = Nothing
End Sub

Depois de executar ambas as formas ficam visíveis.definição frm para nada fez bem...nada.

Depois de settign frm para nada, a única identificador aberto para esta forma é através da referência.

Unload Forms(1)

Estou a ver o problema corretamente?

  • Josh

Outras dicas

Na verdade, VB6 implementa RAII assim como a C++ o que significa que localmente declarados referências a obter automaticamente definido para Nothing no final de um bloco.Da mesma forma, deve repor automaticamente o membro variáveis de classe depois de executar Class_Terminate.No entanto, existem vários relatos de que isso não é feito de forma confiável.Não me lembro de nenhuma teste rigoroso, mas ele sempre foi melhor prática para repor variáveis de membro manualmente.

@Martin

VB6 tinha um "Com/Final Com a" declaração de que trabalhou "como" o Uso() declaração de C#.NET.E, claro, o global, menos coisas você tiver, melhor para você.

Com/Final Com a não trabalhar como Usar a instrução, não "Descarte" no final da instrução.

Com/Final Com obras em VB 6, assim como faz no VB.Net é basicamente uma forma de atalho objeto de propriedades/métodos de chamada.exemplo:

Com aCustomer .Nome = "João" .Apelido = "Smith" Final Com

Objetos em VB tem a contagem de referência.Isso significa que um objeto mantém uma contagem de quantas outras variáveis de objeto conter uma referência para ele.Quando não há referências para o objeto, o objeto é coletado pelo coletor de lixo (eventualmente).Esse processo é parte da especificação de COM.

Geralmente, quando uma localmente instanciado o objeto sai de escopo (por exemplo,sai do sub), sua contagem de referência para baixo, em outras palavras, a variável de referência o objeto é destruído.Assim, na maioria dos casos, você não precisa definir explicitamente um objeto igual a Nada de sair de um Sub.

Em todos os outros casos, você deve definir explicitamente uma variável de objeto para Nada, a fim de diminuir sua contagem de referência (por um).A definição de uma variável de objeto para Nada, não necessariamente destruir o objeto, você deve definir TODAS as referências para Nada.Este problema pode tornar-se particularmente aguda com recursiva estruturas de dados.

Outra pegadinha, é quando usando a palavra-chave New em um objeto de declaração de variável.Um objeto é criado somente no primeiro uso, não no ponto em que a Nova palavra-chave é usada.Utilizando a Nova palavra-chave na declaração de re-criar o objeto na primeira utilização cada vez que a sua contagem de referência para zero.Portanto, a definição de um objeto Nada pode destruí-lo, mas o objeto será automaticamente recriado se referenciado novamente.O ideal é que você não deve declarar a utilizar a Nova palavra-chave, mas usando o operador New, que não tem essa ressurreição comportamento.

Estritamente falando, nunca, mas dá o coletor de lixo um forte indício para limpar as coisas.

Como regra: fazer isso toda vez que você é feito com um objeto que você criou.

A definição de um VB6 referência para Nada, diminui a refecences contar que o VB tem para esse objeto.Se e somente se a contagem for zero, então o objeto será destruído.

Não pense que só porque você definir para Nada será "coleta de lixo", como em .NET

VB6 usa um contador de referência.

Você é encorajado a definir para o "Nada" instanciated objetos que fazem referece ao código C/C++ e coisas assim.Tem sido um longo tempo desde que eu toquei VB6, mas eu lembro de arquivos de configuração e recursos para nada.

Em ambos os casos ele não vai machucar (se Nada fosse feito), mas isso não significa que o objeto será destruído.

VB6 tinha um "Com/Final Com a" declaração de que trabalhou "como" o Uso() declaração de C#.NET.E, claro, o global, menos coisas você tiver, melhor para você.

Lembre-se que, em qualquer dos casos, às vezes, a criação de um objeto grande é mais caro do que manter uma referência viva e reutilizando-os.

Eu tive um problema semelhante a este um tempo atrás.Parece que eu acho que também impediria a aplicação de fechamento, mas pode ser aplicável aqui.

Eu coloquei o código antigo e parece algo como:

Dim y As Long
For y = 0 To Forms.Count -1
    Unload Forms(x)
Next

Pode ser mais seguro para Descarregar o m_frm1.e não basta configurá-lo para nada.

Um ponto importante que ainda não foi mencionado aqui é que a definição de um objeto de referência para Nada fará com que o processo de destruição do objecto para executar (Class_Terminate se a classe foi escrito em VB) se não existem outras referências para o objeto (contagem de referência é zero).

Em alguns casos, especialmente quando se utiliza um RAII padrão, o código de terminação pode executar código que pode gerar um erro.Eu acredito que este é o caso com alguns dos ADODB classes.Outro exemplo é uma classe que encapsula e/s de arquivo, o código da Class_Terminate pode tentar limpar e fechar o arquivo, se ele ainda está aberto, o que pode gerar um erro.

Por isso, é importante estar ciente de que a definição de um objeto de referência para o Nada pode gerar um erro, e lidar com ele de acordo (exatamente como irá depender de sua aplicação - por exemplo, você pode ignorar esses erros inserindo "On Error Resume Next" antes de "Conjunto de ...= Nada").

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