Melhorando o desempenho com o pool de objetos

O agrupamento de objetos pode ser extremamente eficaz em determinadas circunstâncias, gerando aumentos substanciais no desempenho. A ideia geral para reutilizar objetos para obter a melhor vantagem é agrupar o maior número possível de recursos, fatorando a inicialização do trabalho real executado e, em seguida, adaptar administrativamente as características do pool ao hardware real no momento da implantação. Ou seja, você deve proceder de acordo com os seguintes passos:

  1. Escreva o objeto de modo a considerar a inicialização cara e a aquisição de recursos que é executada para qualquer cliente como um pré-requisito para fazer o trabalho real em nome do cliente. Escreva construtores de objetos pesados para agrupar o maior número possível de recursos para que eles sejam mantidos pelo objeto e imediatamente disponíveis quando os clientes obtiverem um objeto do pool.
  2. Configure administrativamente o pool para obter o melhor equilíbrio nos recursos de hardware disponíveis, geralmente negociando a memória dedicada à manutenção de um pool de um determinado tamanho em troca de acesso mais rápido do cliente e uso de objetos. Em um determinado ponto, o pool alcançará retornos decrescentes e você poderá obter desempenho bom o suficiente enquanto limita o possível uso de recursos por um componente específico.

Fazendo trabalho real ou adquirindo recursos

Se você tiver um componente que os clientes usarão brevemente e em rápida sucessão, onde uma parte significativa do tempo de uso do objeto é gasto na aquisição de recursos ou na inicialização antes de fazer um trabalho específico para o cliente, é provável que escrever seu componente para usar o pool de objetos seja uma grande vitória para você.

Você pode escrever o componente para que, no construtor do objeto, você execute o máximo possível do trabalho demorado e uniforme para todos os clientes — adquirindo uma ou várias conexões, executando scripts, buscando dados de inicialização de arquivos ou em uma rede e assim por diante. Isso tem o efeito de reunir todos esses recursos. Você está reunindo a combinação de recursos e estado genérico necessário para executar algum trabalho.

Nessa circunstância, quando os clientes obtêm um objeto do pool, eles têm esses recursos imediatamente disponíveis. Normalmente, eles usarão o objeto para fazer alguma pequena unidade de trabalho, empurrando ou extraindo dados e, em seguida, o objeto chamará IObjectContext::SetComplete ou IObjectContext::SetAbort e retornará. Com padrões de uso rápido como este, o pooling produz excelentes benefícios de desempenho. Você pode aproveitar totalmente a simplicidade do modelo de programação de transações automáticas sem monitoração de estado, mas alcançar um desempenho equivalente aos componentes com monitoração de estado tradicionais.

No entanto, se os clientes usarem um objeto por um longo tempo cada vez que o chamarem, o pool fará menos sentido. A vantagem de velocidade que você ganha é marginal à medida que o tempo de uso aumenta em relação ao tempo de inicialização. Você obtém retornos decrescentes que podem não justificar o custo da memória necessária para manter um pool de objetos ativos.

Compartilhando o custo entre vários clientes

Uma variação na inicialização de fatoração é que você pode usar o pool para amortizar estatisticamente o custo de aquisição de recursos caros. Se você pegar o golpe de aquisição ou inicialização uma vez e, em seguida, reutilizar o objeto, você compartilhar esse custo entre todos os clientes que usam o objeto durante sua vida útil. O tempo de construção pesada é incorrido apenas uma vez por objeto.

Pré-alocação de objetos

Se você especificar um tamanho mínimo de pool diferente de zero, esse número mínimo de objetos será criado e agrupado quando o aplicativo for iniciado, pronto para todos os clientes que ligarem para o aplicativo.

Governando o uso de recursos com o gerenciamento de pool

Você pode usar o tamanho máximo do pool para controlar com muita precisão como você usa os recursos. Por exemplo, se você tiver licenciado um determinado número de conexões de banco de dados, poderá controlar quantas conexões serão abertas a qualquer momento.

Quando você leva em consideração padrões de uso do cliente, características de uso de objeto e recursos físicos, como memória e conexões, é provável que encontre algum ponto de equilíbrio ideal ao fazer o ajuste de desempenho. O agrupamento de objetos produzirá retornos decrescentes após um certo ponto. Você pode determinar o nível de desempenho necessário e balanceá-lo com os recursos necessários para alcançá-lo.

Para facilitar o ajuste de desempenho ao configurar o pool de objetos, você pode monitorar as estatísticas de objetos para os componentes em um aplicativo. Para obter detalhes, consulte Monitorando estatísticas de objeto.

Melhore o desempenho de componentes ativados por JIT

O pool de objetos funciona muito bem com o serviço de ativação just-in-time COM+. Ao agrupar objetos que estão sendo ativados por JIT, você pode acelerar a reativação de objetos. Você obtém os benefícios de manter o canal aberto pela ativação JIT enquanto reduz o custo de reativação. Nesse caso, você pode usar o pool para controlar a quantidade de memória que deseja alocar a objetos que tenham referências ativas.

É mais provável que você esteja agrupando componentes ativados por JIT quando eles são transacionais. O pool de objetos é otimizado para lidar com componentes transacionais. Para obter mais informações, consulte Pooling Transactional Objects.

COM+ Object Construtor Strings

Controlando o tempo de vida e o estado do objeto

Como funciona o pool de objetos

Agrupando objetos transacionais

Requisitos para objetos agrupáveis