Árvore de páginas

Elimina da memória a instância do objeto informado como parâmetro.

Sintaxe

FreeObj( < oObj > )

Parâmetros

Nome

Tipo

Descrição

Obrigatório

Referência

oObj

objeto

Indica o objeto AdvPL a ser eliminado da memória.

X


Observações

  • A função FreeObj() elimina a instância referenciada pelo objeto informado como parâmetro. Esta função é utilizada para eliminar explicitamente a instância do objeto da memória do server, independentemente de haver outras referências aquela instância do objeto. Ao eliminarmos uma instância de objeto utilizando a função FreeObj(), as variáveis que faziam referência à instância eliminada passam a ter conteúdo nulo ( NIL ). Caso alguma referência ao objeto eliminado seja utilizada, a aplicação AdvPL será finalizada com a ocorrência de erro fatal "Variable is not an object".
  • A limpeza de uma instância de uma classe/objeto, na linguagem AdvPL, é realizada normalmente pelo run-time do Kernel do Application Server, quando a variável sai do escopo de processamento e/ou quando a variável é anulada ( oVariavel := NIL ). Porém, caso a instância deste objeto esteja sendo referenciada por mais de uma variável, no momento que uma das variáveis é anulada, é eliminada apenas uma referência, mas a instância do objeto continua ativa, pois ela ainda está sendo referenciada por outra variável. É recomendável o uso da função FreeObj() para objetos de componentes não-visuais, como classes AdvPL e/ou WebServices, uma vez que a determinada instância não será mais utilizada e/ou necessária no processamento, forçando a limpeza da instância do objeto da memória e anulando todas as referências ativas do mesmo.
  • A utilização da função FreeObj() requer cuidado especial quando utilizada para eliminar da memória um objeto de uma classe visual (Objeto de Interface). Se a função for chamada para eliminar um objeto de interface ainda ativo, o Application Server pode apresentar comportamentos inesperados, como ocorrências de "Exception Access Violation", "Segment Fault" , congelamento do serviço e/ou queda do servidor de aplicação.
  • Referência circular em classes AdvPL e consumo de memória: Imagine uma classe AdvPL chamada "MsTeste", onde temos uma propriedade chamada "ObjParent", e durante a utilização do programa, uma instância de MsTeste recebe a si mesma como conteúdo da propriedade objParent, ou ainda, duas instâncias distintas da classe MsTeste, onde uma instância contém a outra alimentada na propriedade oObjParent. Por exemplo :


// Exemplo 1 : Referencia a si mesmo a->a
Local oJustMe := MsTeste():New()
oJustMe:oObjParent := oJustMe
// Exemplo 2 : Referencia Circular a->b e b->a
Local oObj1 := MsTeste():New()
Local oObj2 := MsTeste():New()
oObj1:oObjParent := oObj2oObj2:oObjParent := oObj1


Em ambos os casos mencionados, o objeto foi referenciado de forma "circular", isto é, uma referência do objeto aponta para ele mesmo, ou aponta para outra instância que aponta para a instância original. Neste cenário, o vazamento de memória é caracterizado pelo consumo crescente de memória na aplicação, após sucessivas e consecutivas criações de instâncias do objeto, que podem culminar com a queda do serviço do ERP por esgotamento de memória da máquina e/ou memória alocável pelo serviço, o que for atingido primeiro. A memória excedente alocada nestas condições sempre é completamente liberada ao sistema operacional quando a thread/processo é terminada e/ou o Smart Client é fechado.

Se um programa utiliza uma construção desta natureza, ele deve estar preparado para lidar com este cenário, onde o uso de uma recursão no objeto sem o tratamento adequado colocaria o programa AdvPL em LOOP infinito e/ou até estourar o stack do AdvPL, e deve estar dotado de um procedimento para eliminar uma instância e suas dependências da memória quando o objeto não for mais utilizado. Isto pode ser feito de duas formas :

Atribuindo NIL primeiro nas propriedades do objeto, e então atribuindo NIL no próprio objeto

Utilizando a função FreeObj() quando o objeto não for mais utilizado e/ou necessário no processamento em questão. A presença de uma referência circular em uma classe ou encadeamento de classes AdvPL, sem o destrutor adequado, está sujeito a um "RunTime Leak" (ou vazamento de memória em tempo de execução), onde cada criação de uma nova instância de uma determinada classe não é automaticamente limpa da memória no caso de saída de escopo ou até mesmo atribuindo NIL apenas na variável que contém o objeto, pois o fato dele ainda ter uma referência em uso o impede de ser eliminado da memória, mesmo que a referência esteja em uso por ele mesmo. A implementação deste nível de verificação na execução de código AdvPL seria muito dispendiosa e seria prejudicial à performance da aplicação. Veja o exemplo abaixo :

User Function ExemploReferenciaCircular()
  Local oJustMe := MsTeste():New()
  oJustMe:oObjParent := oJustMe   // Cria a referencia circular
  // processamento ..etc... /
  / processou, vou destruir o objeto.
  oJustMe:oObjParent := NIL
  // primeiro limpa a propriedade
  oJustMe := NIL
  // agora sim limpa o objeto ou , limpa a instancia usando freeobj()
  FreeObj(oJustMe)
return

Exemplo

User Function Exemplo()
  Local oObj := MyClass():New()
  oObj:DoSomething("Hello")
  oObj:DoNothing("Goodbye")
  FreeObj(oObj)
Return

Abrangência

Microsiga Protheus 8.11 , Protheus 10 , TOTVS Application Server 10

  • Sem rótulos