Share via


Gerenciando tempos de vida de objetos por meio da contagem de referência

Em sistemas de objetos tradicionais, o ciclo de vida dos objetos, ou seja, os problemas que envolvem a criação e a exclusão de objetos, é tratado implicitamente pela linguagem (ou pelo tempo de execução da linguagem) ou explicitamente pelos programadores de aplicativos.

Em um sistema evolutivo, construído de forma descentralizada, composto por componentes reutilizados, não é mais verdade que qualquer cliente, ou mesmo qualquer programador, sempre "sabe" como lidar com a vida útil de um componente. Para um cliente com os privilégios de segurança corretos, ainda é relativamente fácil criar objetos por meio de uma solicitação simples, mas a exclusão de objetos é outra questão totalmente diferente. Não está necessariamente claro quando um objeto não é mais necessário e deve ser excluído. (Leitores familiarizados com ambientes de programação coletados por lixo, como Java, podem discordar; no entanto, os objetos Java não abrangem limites de máquina ou mesmo de processo e, portanto, a coleta de lixo é restrita a objetos que vivem em um espaço de processo único. Além disso, o Java força o uso de uma única linguagem de programação.) Mesmo quando o cliente original termina com o objeto, ele não pode simplesmente desligar o objeto, porque algum outro cliente ou clientes ainda podem ter uma referência a ele.

Uma maneira de garantir que um objeto não seja mais necessário é depender inteiramente de um canal de comunicação subjacente para informar o sistema quando todas as conexões com um objeto entre processos ou entre canais desaparecerem. No entanto, esquemas que usam esse método são inaceitáveis por várias razões. Um problema é que isso pode exigir uma grande diferença entre o modelo de programação entre processos/redes e o modelo de programação de processo único. No modelo de programação entre processos/redes cruzadas, o sistema de comunicação forneceria os ganchos necessários para o gerenciamento da vida útil dos objetos, enquanto no modelo de programação de processo único, os objetos são conectados diretamente, sem qualquer canal de comunicação interveniente. Outro problema é que esse esquema também poderia resultar em uma camada de software fornecido pelo sistema que interferiria no desempenho do componente no caso em processo. Além disso, um mecanismo baseado em monitoramento explícito não tenderia a escalar para muitos milhares ou milhões de objetos.

A COM oferece uma abordagem escalável e distribuída para esse conjunto de problemas. Os clientes informam a um objeto quando estão usando-o e quando terminam, e os objetos excluem-se quando não são mais necessários. Essa abordagem exige que todos os objetos contem referências a si mesmos. Linguagens de programação como Java, que inerentemente têm seus próprios esquemas de gerenciamento de vida útil, como coleta de lixo, podem usar a contagem de referência de COM para implementar e usar objetos COM internamente, permitindo que o programador evite lidar com isso.

Assim como um aplicativo deve liberar memória alocada quando essa memória não estiver mais em uso, um cliente de um objeto é responsável por liberar suas referências ao objeto quando esse objeto não for mais necessário. Em um sistema orientado a objetos, o cliente só pode fazer isso dando ao objeto uma instrução para se libertar.

É importante que um objeto seja desalocado quando não estiver mais sendo usado. A dificuldade está em determinar quando é apropriado desalocar um objeto. Isso é fácil com variáveis automáticas (aquelas alocadas na pilha) — elas não podem ser usadas fora do bloco em que são declaradas, então o compilador as desaloca quando o final do bloco é atingido. Para objetos COM, que são alocados dinamicamente, cabe aos clientes de um objeto decidir quando não precisam mais usar o objeto — especialmente objetos locais ou remotos que podem estar em uso por vários clientes ao mesmo tempo. O objeto deve aguardar até que todos os clientes terminem com ele antes de se libertar. Como os objetos COM são manipulados por meio de ponteiros de interface e podem ser usados por objetos em processos diferentes ou em outras máquinas, o sistema não pode controlar os clientes de um objeto.

O método da COM para determinar quando é apropriado desalocar um objeto é a contagem manual de referência. Cada objeto mantém uma contagem de referência que controla quantos clientes estão conectados a ele - ou seja, quantos ponteiros existem para qualquer uma de suas interfaces em qualquer cliente.

Para Mais informações, consulte os seguintes tópicos:

Usando e implementando IUnknown