Por que eu devo ler este artigo:Hoje em dia, quando se fala em qualidade, um dos pontos a serem considerados é o desempenho das aplicações. Um software com boa usabilidade não garante a satisfação do usuário se este precisar esperar muito tempo a cada requisição.

Pensando nisso, neste artigo serão discutidos alguns tópicos que podem auxiliar o desenvolvedor a solucionar muitos dos problemas que provocam lentidão e como consequência, até mesmo o abandono do software.

Devido a maiores necessidades de performance computacional onde um único servidor físico geralmente não possui capacidade de processar grandes volumes de dados ou atender diversas aplicações clientes concorrentes, é comum e recomendável a utilização da computação distribuída para solução rápida e eficiente do problema.

Como consequência da distribuição de um software em diversas plataformas físicas é normal que novos desafios venham a aparecer. Em Java ou até mesmo em outras linguagens existe uma série de cuidados a serem tomados para aproveitar ao máximo as vantagens de um sistema distribuído.

Os ganhos da distribuição da aplicação entre diversas JVMs e diversos servidores podem muitas vezes ser reduzidos devido às más práticas de programação e descuidos ao fazer o planejamento arquitetural do sistema. Diversos problemas podem surgir como o mal uso de dados em cache e o uso extensivo de chamadas remotas.

Em ambientes de grandes empresas, atualmente é comum o uso de arquitetura orientada a serviços (SOA – ver BOX 1) e integração de aplicativos empresariais (EAI – ver BOX 2). Estas arquiteturas envolvem o uso extensivo de chamadas remotas e atividades compostas por diversas aplicações desenvolvidas separadamente.

Estas aplicações geralmente necessitam que sejam compartilhadas uma série de informações para que possuam os recursos básicos para a realização de suas atividades e, às vezes, essas informações podem consumir uma quantidade relevante de memória.

Neste artigo será feita uma análise focada na otimização do uso da memória em um sistema distribuído. Esta análise observará primariamente o uso de chamadas remotas e comunicação entre JVMs. Alguns dos problemas mais comuns serão analisados e algumas soluções serão apresentadas.

BOX 1. SOA

Service-Oriented Architecture é um conjunto de princípios e padrões arquiteturais utilizados para prover funcionalidades de uma aplicação como serviços para outras aplicações. Integração, composição e coordenação de serviços é parte fundamental deste paradigma.

BOX 2. EAI

Enterprise Application Integration é um conjunto de princípios e padrões arquiteturais utilizados para integrar aplicações de diversas tecnologias e/ou empresas de forma simples, segura e eficiente.

Memória alocada x tempo de alocação

Inicialmente é importante avaliarmos uma questão que impacta diretamente na escalabilidade de um sistema distribuído: o tempo que a memória fica alocada durante uma operação, seja esta uma análise de um conjunto de dados ou uma requisição de um aplicativo cliente.

Em um sistema com muitos acessos concorrentes, múltiplas threads serão ativadas simultaneamente e durante a execução do código desta thread serão criados muitos objetos, estes objetos serão utilizados para o processamento de informações e então liberados para coleta via Garbage Collector (GC).

Se as características do sistema forem de criação de muitos objetos e uso de Collections de grande porte para análise de informações ou solução de problemas com muitas variáveis, pode-se chegar muito perigosamente aos limites de memória disponíveis na JVM e/ou no servidor, podendo causar lentidão, falhas ou até mesmo a parada total da aplicação.

Em uma JVM que trabalhe com este tipo de aplicação é, muitas vezes, fácil fazer uma análise do uso de memória e processamento e então delimitar números máximos de clientes concorrentes.

Por exemplo: em uma JVM com limite de memória de 1 GB onde, em média, cada cliente consome 1 MB ao fazer uma requisição e esta requisição demora cerca de 1 segundo para ser atendida, é possível calcular um limite de 1024 clientes concorrentes por segundo.

Neste cálculo é importante observar que por questões de simplicidade estão sendo ignorados os limites de segurança, a alocação básica da aplicação (PermGen), as threads e espaço de alocação estática das classes, entre outras coisas. Multiplicando isto por quatro JVMs, há uma capacidade máxima de 4096 requisições por segundo.

Entretanto, se for possível reduzir não o tempo de processamento, mas sim o tempo que a memória fica alocada, é possível multiplicar em várias vezes a capacidade do sistema. Se neste um segundo (importante dizer que u ...

Quer ler esse conteúdo completo? Tenha acesso completo