Quando tenho que definir uma variável para "Nada" no VB6?
-
09-06-2019 - |
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.
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").