Desenvolvimento - Visual Basic

Visual Basic 6 – Simulação de um GC

Nesse artigo será discutida a limpeza de memória usando uma rotina de limpeza, simulando um GC (Garbage Collection).

por Denis Bittencourt Muniz



Nesse artigo será discutida a limpeza de memória usando uma rotina de limpeza, simulando um GC (Garbage Collection).

Na era de linguagens de programação modernas com ótimos recursos, como, por exemplo, Java e C#, programadores tentam adquirir esses recursos para uso em seu dia-a-dia profissional. Mas e quando o profissional é obrigado a trabalhar com uma ferramenta um pouco desatualizada, como exemplo: VB6 (lembre que já existe a versão 2005, versão oito)?

Alguns programadores tentam simular tais recursos modernos em suas respectivas ferramentas. Um recurso muito importante é o GC (Garbage Collection). "Garbage Collection" quer dizer coletor de lixo. Esse sistema é introduzido para gerenciar a memória, assim evitando o enorme trabalho por parte do programador para gerencia de memória.

Em VB6 não há um gerenciador de memória. O programador destrói objeto por objeto usando a declaração seguinte:

Set Objeto = Nothing

Agora imagine: se você usa vários objetos, seria cansativo destruir um por um. Então é aconselhável uma rotina para limpeza de objetos. A seguir será mostrada uma rotina para a limpeza (destruição) de objetos, de minha autoria:

Sub GC(ParamArray Garbage() As Variant)
    "Por Denis Bittencourt
    "Função para limpeza (Set Obj = Nothing) de objetos
    
    "*Observações:
    "1. Funciona apenas com objetos de alocação dinâmica,
    " ou seja, usando "Set obj = New Classe" e não "Dim obj As New Classe"
    "2. Caso não seja um objeto de alocação dinâmica,
    " campos/propriedades desse objeto serão zerados
    
    On Error Resume Next
    Dim i As Long
    
    For i = LBound(Garbage) To UBound(Garbage)
        If TypeOf Garbage(i) Is Object  Then Set Garbage(i) = Nothing
    Next
End Sub

Como mostrado, o parâmetro "Garbage" é uma lista (quantidade variada de valores que são passados para esse argumento) de Variant"s (Observação: o uso de ParamArray, implica o tipo da lista ser Variant) onde os objetos vão ser passado por referência. Um laço é montado usando os valores inicial e final da posição da lista, que é tratada como um vetor (realmente é um vetor, mas simplificando, trato como uma lista para ter a idéia de vários valores independentes entre si).

Dica: Para descobrir o menor índice em um vetor use a função "LBound". Para descobrir o maior índice em um vetor use a função "UBound". E se for uma matriz? LBound e UBound possuem um segundo parâmetro, opcional, que índica a dimensão que deve ser avaliada.

Voltando a estrutura da função, o tratamento de erro é ativado para evitar comparação com o operando Nothing, palavra-chave que indica referencia nula. Caso a expressão seja:

TypeOf Nothing Is Object

Um erro deveria ocorrer, caso o tratamento estivesse desabilitado. Mas se o objeto em questão não for "Nothing", sua destruição será feita.

Algumas observações finais:

1. Objetos criados com essa sintaxe: Dim Obj As New Classe, terão seus campos/propriedades zerados, visto que é uma alocação feita para persistir até o fim da execução do programa.

2. Objetos criados com essa sintaxe: Set Obj = New Classe, serão destruídos, visto que, provavelmente, o VB usa o recurso de alocação dinâmica, assim podendo retirá-los da memória.

3. Rotina de simulação de um GC, ou seja, não é considerado um GC, visto que um verdadeiro GC oferece muito mais utilidade e seu uso não é controlado pelo programador. Uso o conceito apenas por uma característica: a destruição de uma coleção de objetos.

4. Dica: chame essa rotina no evento Unload de algum formulário ou no evento Terminate de alguma classe. Deixe essa rotina em um módulo. É claro que para obedecer a essa dica para que ocorra a destruição de todos objetos do formulário/classe, tais objetos devem estar com escopo Global, ou seja, declarados na seção "General" e devem ser passados para a função, como ilustra o exemplo abaixo:

GC Excel, Mycollection, Coxecao, Rs "Objetos sendo passado para o parâmetro "Garbage" para que ocorra a destruição dos mesmos. Qualquer tipo de variável é aceito nessa coleção, visto que na estrutura interna da função será avaliado se a expressão contida na posição da lista (vetor) de Variant, que suporta todos os outros tipos de dados, é ou não um objeto.

Até a próxima!

Denis Bittencourt Muniz

Denis Bittencourt Muniz