Tag Archives: java

Effective Java – Item 7 – Elimine referências obsoletas a objetos

Gerenciamento de memória em linguagens com Java, que possuem mecanismo de coleta de lixo, ou garbage collection mechanism, podem evitar problemas de perda de memória, ou “memory leaks“.

As “Memory Leaks” ocorrem quando objetos que já não são utilizados ainda ocupam espaço na memória. Esses objetos estão no Heap e suas variáveis na Stack, no caso do Java.

Não é por haver um mecanismo de coleta de lixo que o programador não deva se preocupar com problemas de memória que um código, até mesmo um simples, pode causar.

Perdas de memória podem gerar uma OutOfMemoryError mas o maior problema é que, na maioria da vezes, ela ocorre de forma silienciosa. E apenas podem ser descobertas com uma inspeção minuciosa do código e com o auxílio de ferramentas de debugging, conhecidas como “heap profiler“.

A classe abaixo armazena um array de objetos, permite o push e o pop de elementos e a cada push, dobra de tamanho.

// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}

O problema dela é no método pop. Quando um objeto é retornado e o tamanho diminuído, a stack ainda mantém uma referência obsoleta a esse objeto. Nessa caso, toda referência que estiver fora da “porção ativa” do array serão obsoletos. A porção ativa equivale aos elementos que o índice for menor que o tamanho do array.

Perda de memórias em linguagens como o Java são também conhecidas como retenção não intencionais de objetos, ou “unintentional object retentions“. Esses objetos ficam excluídos do coleta de lixo assim como objetos que ele possa referênciar, e assim por diante.

E a solução? Tornar nulas as referências assim que um objeto se tornar obsoleto. Segue o treco do código com a solução.

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}

Mas cuidado. Tornar nula referências a objetos deve ser exceção e não regra. E a melhor maneira de eliminar referências obsoletas é definar cada variável num menor escopo possível.

Então quando se deve usar o “null out”? Quais aspectos tornam uma classe suscetível a “memory leaks”? De maneira simples, sempre que houver uma espécie de memória e que seja gerida por ela. No caso da classe Stack, é o array de elementos e seus métodos para incluir e remover. O garbage collector não tem como saber se um elemento está inválido, uma vez que guarda a referência aos objetos e não eles em si. Portanto, isso deve ser feito manualmente pelo programador.

Até o próximo item.

Effective Java – Item 6

Avoid creating unnecessary objects (evite criar objetos desnecessários)

O item do livro diz que é mais apropriado reusar objetos ao invés de criar novos objetos funcionalmente equivalentes cada vez que for necessário. Um objeto pode sempre ser reutilizado se for imutável.

O primeiro exemplo dado é a crição de uma String.

String s = new String("bikini"); // DON'T DO THIS!

Esse código cria uma instância cada vez que é executado e nenhum deles é necessário. O argumento do construtor (“bikini”) já é uma String.

O correto é String s = "bikini";

Em um loop, nesse caso, apenas uma única instância é criado, ao invés de uma para cada vez que for executado.

E se na mesma VM outro objeto contendo “bikini” reusará a instância já criada.

O código abaixo, que verifica se uma String é um numeral romano, e da forma como foi escrito, criará sempre um Pattern para expressão regular, o que é muito caro para a VM.

// Performance can be greatly improved!
static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}

O certo seria criar um objeto imutável que seria reutilizado nas chamadas ao método.

// Reusing expensive object for improved performance
public class RomanNumerals {
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})"
+ "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumeral(String s) {
return ROMAN.matcher(s).matches();
}
}

 Esse código acima rodou 6.5 vezes mais rápido.

Um outro exemplo, que pode levar ao aumento de utilização de recursos, é utilizar o autoboxing, isto é, poder utilizar juntos primitivos e objetos que os encapsulam. Exemplo de long, primitivo, e Long, objeto.

// Hideously slow! Can you spot the object creation?
private static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++)
sum += i;
return sum;
}

O código acima criará 2^31 instâncias de Long desnecessárias. Desta forma, “prefira tipos primitivos a objetos que os encapsulem e tome cuidado nos autoboxing não intencionais”.

Essa parte do livro foi muito interessante pois são situações diárias e que se não forem observadas podem contribuir para diminuir a performance de aplicações.

Segue o link do livro.

 

Java @Schedule error

I was trying to scheduling a method from a EJB class using the @Schedule annotation of the javax.ejb package.

@Schedule(second=”*/5″, minute=”*”, hour=”*”)
public void listarMsgs()
{
logger.log(Level.INFO, “do something…”);
}

But every time the method was called it  appeared a error like this:

Failed to reinstate timer…

Googling for about some time I figure out that it was a kind bug of the application server, JBoss Wildfly. I’m using the 9 version.

The solution was clear the folder under the standalone/data/timer-service-data that is where the server creates the xml of the schedule job.

Microservices boundaries

Fronteira entre serviços

Sob a nova perspectiva de softwares como microservices surge um desafio em identificar as fronteiras entre estes que compõem a aplicação.

Duas abordagens podem ser consideradas, ambas baseadas no princípio da Single Responsible Principle (Princípio da Responsabilidade Única):

A primeira estabelece que os microservices devem ser identificados por meio do verbo de execução de sua responsabilidade. Por exemplo, em uma aplicação de Gerência de Estoques, como a twarehouse em tetraTI, ao analisarmos as ações de entrada de produtos, o cadastro e análise daqueles com baixa em estoque, teríamos assim 3 candidatos a microservices: Entrada de Produtos Service, Cadastro de Produtos Service e Analisador de Baixa Service.

A outra abordagem é a de definir fronteiras por meio da identificação das entidades ou recursos oferecidos pelo sistema. Dessa forma e utilizando o exemplo acima teríamos serviços como Movimentação Service, responsável por todas as operações de movimentação. Ou Analisador de Estoque Service, que forneceria informações em tempo real sobre o estoque.

É muito sutil a escolha ou identificação de serviços por meio de suas fronteiras, que juntos definem a aplicação em si. Para enfrentar este desafio deste novo conceito de SaaS e usufruir de suas vantagens será necessário bom senso e experiência por parte do arquiteto.

Fonte: Devmedia e Building Microservices Book.

Conteúdo estático no Wildfly em produção

upload-cloud

Neste Post demonstrarei como utilizar de forma eficiente imagens como conteúdo estático em uma aplicação Java Web com JSF que rode em um ambiente Linux e num servidor WildFly 8.x.

A ideia é utilizar imagens no cadastro de produtos, fazendo seu upload e exibindo-as em diversas partes.

upload_1

As ferramentas necessárias são o PuTTy para criação do diretório no servidor e um editor xml para configuração do Handler no arquivo de configuração do WildFly. No meu caso utilizei o próprio Eclise IDE. Claro que assumindo que já exista uma aplicação com as devidas configurações e rodando. Disponibilizarei a classe que utilizo para tratar o upload da imagem também.

Criando a estrutura de diretório: a aplicação está hospedada num servidor integrator.com.br, portanto definia a seguinte estrutura:

upload_2

Para criação dos diretório é necessário pelo PuTTy criar os diretórios a partir da pasta home, assim: /home/<<usuário>>/var/static/images/pecas.

Configurando o handler no WildFly: agora que as pastas estão criadas é necessário mapear esta estrutura no servidor de aplicação para que possamos acessá-lo. Para isso configuramos o arquivo de configuração, standalone.xml, da seguinte forma:

upload_3

O handler mapeará o caminho definido em /imagens/meu-espaco. Para acessar o conteúdo do diretório basta acessar a url http://<<endereço_do_servidor>>/imagens/meu-espaco.  A opção directory-listing permite que seu conteúdo seja listado:

upload_4

A classe para upload da imagem: o mecanismo de upload é simples graças ao componente Upload da biblioteca PrimeFaces. Sua utilização é simples:
upload_5

A classe FotoProdutoBean encaminhará a ação à Camada de Serviço de produto, que utilizará a classe FotoHelper para escrever o conteúdo do download para o diretório definido.

upload_6

A constante CAMINHO_DAS_FOTOS contém o caminho para o nosso diretório de conteúdo estático, isto é, nossas fotos de produtos (peças): /home/meuvisua/var/static/images/pecas/.

Exibindo as imagens: Enfim, para exibir a imagem basta uma tab <img> html com o mapeamento. Desta forma:

upload_7

Só isso! Ao utilizarmos o handler para mapear um diretório fora do servidor de aplicação tornamos nosso conteúdo estático independente. Num cenário de atualização ou substituição do servidor nada será afetado. Ainda, assim evitamos também salvarmos essas imagens direto no banco, impactando a performance.

Se alguém tiver uma solução melhor ou alternativa, comentem.

Até o próximo.