Aprimorando o Desempenho com Mapas de Matriz de Byte

É possível armazenar os valores em seus mapas em uma matriz de byte em vez do formulário POJO, o que reduz a área de cobertura da memória que um grande gráfico de objetos pode consumir.

Vantagens

A quantidade de memória que é consumida aumenta com o número de objetos em um gráfico de objetos. Ao reduzir um gráfico de objetos complicado a uma matriz de bytes, somente um objeto é mantido na pilha em vez de vários objetos. Com esta redução do número de objetos na pilha, o tempo de execução Java tem menos objetos para procurar durante a coleta de lixo.

O mecanismo de cópia padrão usado pelo WebSphere eXtreme Scale é a serialização, que é dispendiosa. Por exemplo, se o modo de cópia padrão de COPY_ON_READ_AND_COMMIT é usado, uma cópia é feita no tempo de leitura e no tempo de obtenção. Em vez de fazer uma cópia no tempo de leitura, com matrizes de byte, o valor é aumentado a partir dos bytes, e em vez de fazer uma cópia no tempo de consolidação, o valor é serializado para bytes. Usar matrizes de byte resulta em consistência de dados equivalentes à configuração padrão com uma redução da memória usada.

Ao usar matrizes de byte, note que ter um mecanismo de serialização otimizado é crítico para ver uma redução do consumo de memória. Para obter mais informações, consulte Ajustando o Desempenho de Serialização.

Configurando Mapas de Matriz de Byte

É possível ativar mapas de matriz de byte com o arquivo XML ObjectGrid modificando o atributo CopyMode que é usado por um mapa para a configuração COPY_TO_BYTES, mostrada no exemplo a seguir:

<backingMap name="byteMap" copyMode="COPY_TO_BYTES" />

Considerações

Você deve considerar se usará ou não os mapas da matriz de byte em um determinado cenário. Embora seja possível reduzir o uso de memória, o uso do processador aumenta quando você usa matrizes de byte.

A seguinte lista destaca vários fatores que devem ser considerados antes de escolher usar da função do mapa de matriz de byte.

Tipo de Objeto

Comparativamente, a redução de memória pode não ser possível com o uso de mapas de matriz de byte para alguns tipos de objeto. Consequentemente, vários tipos de objetos existem para os quais você não deve usar mapas de matriz de byte. Se você estiver usando qualquer um dos wrappers primitivos Java como valores, ou um POJO que não contenha referências a outros objetos (somente campos primitivos de armazenamento), o número de Objetos Java já é o mais baixo possível–há apenas um. Como a quantidade de memória usada pelo objeto já está otimizada, usar um mapa de matriz de byte para esses tipos de objetos não é recomendado. Os mapas de matriz de byte são mais adequados a tipos de objeto que contenham outros objetos ou coletas de objetos nos quais o número total de objetos POJO seja maior que um.

Por exemplo, se você tiver um objeto Cliente que tenha um Endereço comercial e um Endereço residencial, assim como uma coleta de Pedidos, o número de objetos na heap e o número de bytes usados por esses objetos pode ser reduzido usando-se mapas de matriz de byte.

Acesso local

Ao usar outros modos de cópia, os aplicativos poderão ser otimizados quando as cópias forem feitas, se os objetos forem Clonáveis com o ObjectTransformer padrão ou quando um ObjectTransformer customizado for fornecido com um método copyValue otimizado. Comparado com outros modos de cópia, a cópia de operações de leituras, gravações ou consolidações terá um custo adicional ao acessar os objetos localmente. Por exemplo, se você tiver um cache perto em uma topologia distribuída ou estiver acessando diretamente uma instância ObjectGrid local ou de servidor, o tempo de acesso e de confirmação aumentará com o uso de mapas de matriz de bytes devido ao custo de serialização. Você verá um custo similar em uma topologia distribuída se usar agentes da grade de dados ou acessar o servidor primário ao utilizar o plug-in ObjectGridEventGroup.ShardEvents.

Interações de Plug-in

Com mapas de matriz de byte, os objetos não são aumentados durante a comunicação de um cliente com um servidor a menos que o servidor precise do formulário POJO. Os plug-ins que interagem com o valor do mapa experimentarão uma redução no desempenho devido ao requisito para aumentar o valor.

Qualquer plug-in que use o LogElement.getCacheEntry ou LogElement.getCurrentValue verá esse custo adicional. Se você desejar obter a chave, é possível usar LogElement.getKey, que evita o custo adicional associado com o método LogElement.getCacheEntry().getKey. As seções a seguir discutem os plug-ins sob a perspectiva do uso de matrizes de byte.

Índices e consultas

Quando os objetos são armazenados em formato POJO, o custo de fazer indexação e consulta é mínimo porque o objeto não precisa ser aumentado. Ao usar um mapa de matriz de byte, você terá o custo adicional de aumentar o objeto. Em geral, se o seu aplicativo usar índices ou consultas, é recomendado usar mapas de matriz de byte a menos que você execute somente consultas sobre atributos-chave.

Bloqueio Otimista

Ao usar a estratégia de bloqueio otimista, você terá o custo adicional durante atualizações e operações inválidas. Isso advém da necessidade de aumentar o valor no servidor para obter o valor da versão para fazer verificação de colisão otimista. Se você estiver apenas usando o bloqueio otimista para garantir operações de busca e não precisar de verificação de colisão otimista, é possível usar o com.ibm.websphere.objectgrid.plugins.builtins.NoVersioningOptimisticCallback para desativar a verificação de versão.

Utilitário de carga

Com um Utilitário de Carga, você também terá o custo no tempo de execução do eXtreme Scale de aumentar e reserializar o valor quando ele for usado pelo Utilitário de Carga. Também é possível usar mapas de matriz de byte com Utilitários de Carga, mas considere o custo de fazer alterações no valor em tal cenário. Por exemplo, é possível usar o recurso de matriz de byte no contexto de um cache principalmente de leitura. Neste caso, o benefício de ter menos objetos na heap e menos memória usada excederá o custo incorrido de usar matrizes de byte em operações de inserção e atualização.

ObjectGridEventListener

Ao utilizar o método transactionEnd method no plug-in ObjectGridEventListener, você terá um custo adicional no lado do servidor para pedidos remotos ao acessar um CacheEntry ou o valor atual de LogElement. Se a implementação do método não acessar esses campos, então você não terá o custo adicional.